diff --git a/Makefile.in b/Makefile.in index ee28d0fccb..0287915717 100644 --- a/Makefile.in +++ b/Makefile.in @@ -766,13 +766,22 @@ mptest: mptester$(TEXE) $(MPTEST2) --journalmode DELETE +has_tclsh84: + sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) + touch has_tclsh84 + +has_tclsh85: + sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) + touch has_tclsh85 + + # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c +.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl has_tclsh84 fts5.c rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc @@ -782,15 +791,15 @@ mptest: mptester$(TEXE) cp fts5.c fts5.h tsrc touch .target_source -sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify +sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . -sqlite3r.h: sqlite3.h +sqlite3r.h: sqlite3.h has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -sqlite3r.c: sqlite3.c sqlite3r.h +sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ @@ -805,7 +814,7 @@ tclsqlite3.c: sqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c -sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl +sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl # Rule to build the amalgamation @@ -1093,10 +1102,10 @@ tclsqlite3$(TEXE): tclsqlite-shell.lo libsqlite3.la # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c -opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl +opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl has_tclsh84 cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. @@ -1107,10 +1116,10 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) cp $(TOP)/src/parse.y . ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h -sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION +sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ cat $(TOP)/VERSION | $(TCLSH_CMD) $(TOP)/tool/replace.tcl exact . , >>$@ @@ -1146,7 +1155,7 @@ SHELL_SRC = \ $(TOP)/ext/recover/sqlite3recover.h \ $(TOP)/src/test_windirent.c -shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl +shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c @@ -1234,7 +1243,7 @@ fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) +fts5.c: $(FTS5_SRC) has_tclsh84 $(TCLSH_CMD) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . @@ -1268,7 +1277,7 @@ TESTFIXTURE_SRC1 = sqlite3.c TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) -testfixture$(TEXE): $(TESTFIXTURE_SRC) +testfixture$(TEXE): has_tclsh85 $(TESTFIXTURE_SRC) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS) @@ -1319,17 +1328,23 @@ testrunner: testfixture$(TEXE) # Runs both fuzztest and testrunner, consecutively. # -devtest: testfixture$(TEXE) fuzztest testrunner +devtest: srctree-check testfixture$(TEXE) fuzztest testrunner -mdevtest: +mdevtest: srctree-check has_tclsh85 $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest -sdevtest: +sdevtest: has_tclsh85 $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest +# Validate that various generated files in the source tree +# are up-to-date. +# +srctree-check: $(TOP)/tool/srctree-check.tcl + $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl + # Testing for a release # -releasetest: testfixture$(TEXE) +releasetest: srctree-check testfixture$(TEXE) ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl release # Minimal testing that runs in less than 3 minutes @@ -1340,7 +1355,7 @@ quicktest: ./testfixture$(TEXE) # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # -test: fuzztest sourcetest $(TESTPROGS) tcltest +test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest # Run a test using valgrind. This can take a really long time # because valgrind is so much slower than a native machine. @@ -1358,13 +1373,13 @@ smoketest: $(TESTPROGS) fuzzcheck$(TEXE) shelltest: $(TESTPROGS) ./testfixture$(TEXT) $(TOP)/test/permutations.test shell -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(TEXE): sqlite3_analyzer.c $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) -sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in +sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in has_tclsh85 $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(TEXE): sqltclsh.c @@ -1383,7 +1398,7 @@ CHECKER_DEPS =\ $(TOP)/ext/misc/btreeinfo.c \ $(TOP)/ext/repair/sqlite3_checker.c.in -sqlite3_checker.c: $(CHECKER_DEPS) +sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ sqlite3_checker$(TEXE): sqlite3_checker.c @@ -1549,6 +1564,7 @@ clean: rm -f threadtest5 rm -f src-verify rm -f custom.rws + rm -f has_tclsh84 has_tclsh85 distclean: clean rm -f sqlite_cfg.h config.log config.status libtool Makefile sqlite3.pc \ @@ -1593,7 +1609,7 @@ fiddle: sqlite3.c shell.c @echo 'Updating custom dictionary from tool/custom.txt' aspell --lang=en create master ./custom.rws < $< -misspell: ./custom.rws +misspell: ./custom.rws has_tclsh84 $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in # diff --git a/Makefile.msc b/Makefile.msc index fe442ff027..8ef8bd13b1 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -52,8 +52,8 @@ MINIMAL_AMALGAMATION = 0 USE_STDCALL = 0 !ENDIF -# Set this non-0 to use structured exception handling (SEH) for WAL mode -# in the core library. +# Use the USE_SEH=0 option on the nmake command line to omit structured +# exception handling (SEH) support. SEH is on by default. # !IFNDEF USE_SEH USE_SEH = 1 @@ -403,10 +403,11 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1 !ENDIF # Should structured exception handling (SEH) be enabled for WAL mode in -# the core library? +# the core library? It is on by default. Only omit it if the +# USE_SEH=0 option is provided on the nmake command-line. # -!IF $(USE_SEH)!=0 -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_USE_SEH=1 +!IF $(USE_SEH)==0 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_OMIT_SEH=1 !ENDIF # These are the "extended" SQLite compilation options used when compiling for diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 13663d8777..8a64e8f46f 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -52,8 +52,8 @@ MINIMAL_AMALGAMATION = 0 USE_STDCALL = 0 !ENDIF -# Set this non-0 to use structured exception handling (SEH) for WAL mode -# in the core library. +# Use the USE_SEH=0 option on the nmake command line to omit structured +# exception handling (SEH) support. SEH is on by default. # !IFNDEF USE_SEH USE_SEH = 1 @@ -325,10 +325,11 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1 !ENDIF # Should structured exception handling (SEH) be enabled for WAL mode in -# the core library? +# the core library? It is on by default. Only omit it if the +# USE_SEH=0 option is provided on the nmake command-line. # -!IF $(USE_SEH)!=0 -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_USE_SEH=1 +!IF $(USE_SEH)==0 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_OMIT_SEH=1 !ENDIF # These are the "extended" SQLite compilation options used when compiling for diff --git a/configure b/configure index 46216308c0..7b31f6f7e8 100755 --- a/configure +++ b/configure @@ -11345,7 +11345,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking build type" >&5 $as_echo_n "checking build type... " >&6; } if test "${enable_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" + TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall" { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5 $as_echo "debug" >&6; } else diff --git a/configure.ac b/configure.ac index 78649a51fd..837d2fb015 100644 --- a/configure.ac +++ b/configure.ac @@ -632,7 +632,7 @@ AC_SEARCH_LIBS(fdatasync, [rt]) AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],[enable debugging & verbose explain])) AC_MSG_CHECKING([build type]) if test "${enable_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" + TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall" AC_MSG_RESULT([debug]) else TARGET_DEBUG="-DNDEBUG" diff --git a/ext/expert/sqlite3expert.c b/ext/expert/sqlite3expert.c index 2d19f7a23a..57baf1ffc1 100644 --- a/ext/expert/sqlite3expert.c +++ b/ext/expert/sqlite3expert.c @@ -662,6 +662,7 @@ static int idxRegisterVtab(sqlite3expert *p){ 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0, /* xIntegrity */ }; return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p); @@ -1866,9 +1867,9 @@ int registerUDFs(sqlite3 *dbSrc, sqlite3 *dbDst){ while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ int nargs = sqlite3_column_int(pStmt,3); int flags = sqlite3_column_int(pStmt,4); - const unsigned char *name = sqlite3_column_text(pStmt,0); - const unsigned char *type = sqlite3_column_text(pStmt,1); - const unsigned char *enc = sqlite3_column_text(pStmt,2); + const char *name = (char*)sqlite3_column_text(pStmt,0); + const char *type = (char*)sqlite3_column_text(pStmt,1); + const char *enc = (char*)sqlite3_column_text(pStmt,2); if( name==0 || type==0 || enc==0 ) rc = SQLITE_NOMEM; else{ int ienc = SQLITE_UTF8; diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 8aa824bce4..491a658871 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -640,6 +640,7 @@ static void fts3DeclareVtab(int *pRc, Fts3Table *p){ zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(p->db, SQLITE_VTAB_INNOCUOUS); /* Create a list of user columns for the virtual table */ zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); @@ -3889,6 +3890,8 @@ static int fts3RenameMethod( rc = sqlite3Fts3PendingTermsFlush(p); } + p->bIgnoreSavepoint = 1; + if( p->zContentTbl==0 ){ fts3DbExec(&rc, db, "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", @@ -3916,6 +3919,8 @@ static int fts3RenameMethod( "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", p->zDb, p->zName, zName ); + + p->bIgnoreSavepoint = 0; return rc; } @@ -3926,12 +3931,28 @@ static int fts3RenameMethod( */ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; - UNUSED_PARAMETER(iSavepoint); - assert( ((Fts3Table *)pVtab)->inTransaction ); - assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint ); - TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); - if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ - rc = fts3SyncMethod(pVtab); + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint<=iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + + if( pTab->bIgnoreSavepoint==0 ){ + if( fts3HashCount(&pTab->aIndex[0].hPending)>0 ){ + char *zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", + pTab->zDb, pTab->zName, pTab->zName + ); + if( zSql ){ + pTab->bIgnoreSavepoint = 1; + rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0); + pTab->bIgnoreSavepoint = 0; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; + } } return rc; } @@ -3942,12 +3963,11 @@ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** This is a no-op. */ static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); - UNUSED_PARAMETER(iSavepoint); - UNUSED_PARAMETER(pVtab); - assert( p->inTransaction ); - assert( p->mxSavepoint >= iSavepoint ); - TESTONLY( p->mxSavepoint = iSavepoint-1 ); + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint >= iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint-1 ); + pTab->iSavepoint = iSavepoint; return SQLITE_OK; } @@ -3957,11 +3977,13 @@ static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** Discard the contents of the pending terms table. */ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts3Table *p = (Fts3Table*)pVtab; + Fts3Table *pTab = (Fts3Table*)pVtab; UNUSED_PARAMETER(iSavepoint); - assert( p->inTransaction ); - TESTONLY( p->mxSavepoint = iSavepoint ); - sqlite3Fts3PendingTermsClear(p); + assert( pTab->inTransaction ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + if( (iSavepoint+1)<=pTab->iSavepoint ){ + sqlite3Fts3PendingTermsClear(pTab); + } return SQLITE_OK; } diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h index 3a8a884f92..5a5b123b4c 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -265,6 +265,7 @@ struct Fts3Table { int nPgsz; /* Page size for host database */ char *zSegmentsTbl; /* Name of %_segments table */ sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ + int iSavepoint; /* ** The following array of hash tables is used to buffer pending index diff --git a/ext/fts3/fts3_aux.c b/ext/fts3/fts3_aux.c index d3b194c942..439d579366 100644 --- a/ext/fts3/fts3_aux.c +++ b/ext/fts3/fts3_aux.c @@ -545,7 +545,8 @@ int sqlite3Fts3InitAux(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ diff --git a/ext/fts3/fts3_term.c b/ext/fts3/fts3_term.c index 47e244e22c..f3a9746a09 100644 --- a/ext/fts3/fts3_term.c +++ b/ext/fts3/fts3_term.c @@ -362,7 +362,8 @@ int sqlite3Fts3InitTerm(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ diff --git a/ext/fts3/fts3_tokenize_vtab.c b/ext/fts3/fts3_tokenize_vtab.c index 65d7eef4c3..7e8d09bd48 100644 --- a/ext/fts3/fts3_tokenize_vtab.c +++ b/ext/fts3/fts3_tokenize_vtab.c @@ -445,7 +445,8 @@ int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index de07c52c13..08884a1b1b 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -3325,7 +3325,6 @@ int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } - sqlite3Fts3PendingTermsClear(p); /* Determine the auto-incr-merge setting if unknown. If enabled, ** estimate the number of leaf blocks of content to be written @@ -3347,6 +3346,10 @@ int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ rc = sqlite3_reset(pStmt); } } + + if( rc==SQLITE_OK ){ + sqlite3Fts3PendingTermsClear(p); + } return rc; } @@ -4034,9 +4037,13 @@ static int fts3IncrmergeAppend( nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; /* If the current block is not empty, and if adding this term/doclist - ** to the current block would make it larger than Fts3Table.nNodeSize - ** bytes, write this block out to the database. */ - if( pLeaf->block.n>0 && (pLeaf->block.n + nSpace)>p->nNodeSize ){ + ** to the current block would make it larger than Fts3Table.nNodeSize bytes, + ** and if there is still room for another leaf page, write this block out to + ** the database. */ + if( pLeaf->block.n>0 + && (pLeaf->block.n + nSpace)>p->nNodeSize + && pLeaf->iBlock < (pWriter->iStart + pWriter->nLeafEst) + ){ rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); pWriter->nWork++; @@ -4368,7 +4375,7 @@ static int fts3IncrmergeLoad( rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc - ); + ); if( rc==SQLITE_OK ){ memcpy(pNode->block.a, aBlock, nBlock); pNode->block.n = nBlock; @@ -5433,8 +5440,11 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ rc = fts3DoIncrmerge(p, &zVal[6]); }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ rc = fts3DoAutoincrmerge(p, &zVal[10]); + }else if( nVal==5 && 0==sqlite3_strnicmp(zVal, "flush", 5) ){ + rc = sqlite3Fts3PendingTermsFlush(p); + } #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - }else{ + else{ int v; if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ v = atoi(&zVal[9]); @@ -5452,8 +5462,8 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; rc = SQLITE_OK; } -#endif } +#endif return rc; } diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index f527709237..4e6afb2815 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -2904,7 +2904,6 @@ static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){ assert_nc( i2!=0 ); pRes->bTermEq = 1; if( p1->iRowid==p2->iRowid ){ - p1->bDel = p2->bDel; return i2; } res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1; @@ -5132,34 +5131,39 @@ static void fts5DoSecureDelete( /* Set variable bLastInDoclist to true if this entry happens to be ** the last rowid in the doclist for its term. */ - if( iNextOff>=iPgIdx ){ - int pgno = pSeg->iLeafPgno+1; - fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); - iNextOff = iPgIdx; - }else{ - /* Loop through the page-footer. If iNextOff (offset of the - ** entry following the one we are removing) is equal to the - ** offset of a key on this page, then the entry is the last - ** in its doclist. */ - int iKeyOff = 0; - for(iIdx=0; iIdxbDel==0 ){ + if( iNextOff>=iPgIdx ){ + int pgno = pSeg->iLeafPgno+1; + fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); + iNextOff = iPgIdx; + }else{ + /* Loop through the page-footer. If iNextOff (offset of the + ** entry following the one we are removing) is equal to the + ** offset of a key on this page, then the entry is the last + ** in its doclist. */ + int iKeyOff = 0; + for(iIdx=0; iIdxbDel ){ + iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta); + aPg[iOff++] = 0x01; + }else if( bLastInDoclist==0 ){ if( iNextOff!=iPgIdx ){ u64 iNextDelta = 0; iNextOff += fts5GetVarint(&aPg[iNextOff], &iNextDelta); @@ -5271,6 +5275,15 @@ static void fts5DoSecureDelete( } } + /* Assuming no error has occurred, this block does final edits to the + ** leaf page before writing it back to disk. Input variables are: + ** + ** nPg: Total initial size of leaf page. + ** iPgIdx: Initial offset of page footer. + ** + ** iOff: Offset to move data to + ** iNextOff: Offset to move data from + */ if( p->rc==SQLITE_OK ){ const int nMove = nPg - iNextOff; /* Number of bytes to move */ int nShift = iNextOff - iOff; /* Distance to move them */ @@ -5471,10 +5484,16 @@ static void fts5FlushOneHash(Fts5Index *p){ fts5WriteFlushLeaf(p, &writer); } }else{ - int bDummy; - int nPos; - int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy); - nCopy += nPos; + int bDel = 0; + int nPos = 0; + int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDel); + if( bDel && bSecureDelete ){ + fts5BufferAppendVarint(&p->rc, pBuf, nPos*2); + iOff += nCopy; + nCopy = nPos; + }else{ + nCopy += nPos; + } if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){ /* The entire poslist will fit on the current leaf. So copy ** it in one go. */ @@ -5512,7 +5531,6 @@ static void fts5FlushOneHash(Fts5Index *p){ assert( pBuf->n<=pBuf->nSpace ); if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); } - sqlite3Fts5HashClear(pHash); fts5WriteFinish(p, &writer, &pgnoLast); assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 ); @@ -5545,7 +5563,6 @@ static void fts5FlushOneHash(Fts5Index *p){ fts5IndexCrisismerge(p, &pStruct); fts5StructureWrite(p, pStruct); fts5StructureRelease(pStruct); - p->nContentlessDelete = 0; } /* @@ -5556,8 +5573,12 @@ static void fts5IndexFlush(Fts5Index *p){ if( p->nPendingData || p->nContentlessDelete ){ assert( p->pHash ); fts5FlushOneHash(p); - p->nPendingData = 0; - p->nPendingRow = 0; + if( p->rc==SQLITE_OK ){ + sqlite3Fts5HashClear(p->pHash); + p->nPendingData = 0; + p->nPendingRow = 0; + p->nContentlessDelete = 0; + } } } @@ -8299,7 +8320,8 @@ int sqlite3Fts5IndexInit(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; rc = sqlite3_create_module(db, "fts5_structure", &fts5structure_module, 0); } diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 6a8ed37b54..d4a36a22aa 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -117,6 +117,8 @@ struct Fts5FullTable { Fts5Storage *pStorage; /* Document store */ Fts5Global *pGlobal; /* Global (connection wide) data */ Fts5Cursor *pSortCsr; /* Sort data from this cursor */ + int iSavepoint; /* Successful xSavepoint()+1 */ + int bInSavepoint; #ifdef SQLITE_DEBUG struct Fts5TransactionState ts; #endif @@ -408,6 +410,9 @@ static int fts5InitVtab( if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1); } + if( rc==SQLITE_OK ){ + rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + } if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); @@ -1530,6 +1535,7 @@ static int fts5SpecialInsert( Fts5Config *pConfig = pTab->p.pConfig; int rc = SQLITE_OK; int bError = 0; + int bLoadConfig = 0; if( 0==sqlite3_stricmp("delete-all", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ @@ -1541,6 +1547,7 @@ static int fts5SpecialInsert( }else{ rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage); } + bLoadConfig = 1; }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NONE ){ fts5SetVtabError(pTab, @@ -1550,6 +1557,7 @@ static int fts5SpecialInsert( }else{ rc = sqlite3Fts5StorageRebuild(pTab->pStorage); } + bLoadConfig = 1; }else if( 0==sqlite3_stricmp("optimize", zCmd) ){ rc = sqlite3Fts5StorageOptimize(pTab->pStorage); }else if( 0==sqlite3_stricmp("merge", zCmd) ){ @@ -1562,6 +1570,8 @@ static int fts5SpecialInsert( }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){ pConfig->bPrefixIndex = sqlite3_value_int(pVal); #endif + }else if( 0==sqlite3_stricmp("flush", zCmd) ){ + rc = sqlite3Fts5FlushToDisk(&pTab->p); }else{ rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); if( rc==SQLITE_OK ){ @@ -1575,6 +1585,12 @@ static int fts5SpecialInsert( } } } + + if( rc==SQLITE_OK && bLoadConfig ){ + pTab->p.pConfig->iCookie--; + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + } + return rc; } @@ -2597,8 +2613,12 @@ static int fts5RenameMethod( sqlite3_vtab *pVtab, /* Virtual table handle */ const char *zName /* New name of table */ ){ + int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - return sqlite3Fts5StorageRename(pTab->pStorage, zName); + pTab->bInSavepoint = 1; + rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); + pTab->bInSavepoint = 0; + return rc; } int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ @@ -2612,9 +2632,29 @@ int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ ** Flush the contents of the pending-terms table to disk. */ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint); - return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + int rc = SQLITE_OK; + char *zSql = 0; + fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); + + if( pTab->bInSavepoint==0 ){ + zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", + pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName + ); + if( zSql ){ + pTab->bInSavepoint = 1; + rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0); + pTab->bInSavepoint = 0; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; + } + } + + return rc; } /* @@ -2623,9 +2663,16 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** This is a no-op. */ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint); - return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + int rc = SQLITE_OK; + fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint); + if( (iSavepoint+1)iSavepoint ){ + rc = sqlite3Fts5FlushToDisk(&pTab->p); + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint; + } + } + return rc; } /* @@ -2635,11 +2682,14 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ */ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ + int rc = SQLITE_OK; fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); pTab->p.pConfig->pgsz = 0; - return sqlite3Fts5StorageRollback(pTab->pStorage); + if( (iSavepoint+1)<=pTab->iSavepoint ){ + rc = sqlite3Fts5StorageRollback(pTab->pStorage); + } + return rc; } /* diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 0a0af9d4b5..9480da7c52 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -1184,7 +1184,9 @@ int sqlite3Fts5StorageSync(Fts5Storage *p){ i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); - p->bTotalsValid = 0; + if( rc==SQLITE_OK ){ + p->bTotalsValid = 0; + } } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexSync(p->pIndex); diff --git a/ext/fts5/fts5_test_tok.c b/ext/fts5/fts5_test_tok.c index a5d839da66..994d304dc6 100644 --- a/ext/fts5/fts5_test_tok.c +++ b/ext/fts5/fts5_test_tok.c @@ -472,7 +472,8 @@ int sqlite3Fts5TestRegisterTok(sqlite3 *db, fts5_api *pApi){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 18774c4e4a..d738ada311 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -783,7 +783,8 @@ int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; void *p = (void*)pGlobal; diff --git a/ext/fts5/test/fts5faultG.test b/ext/fts5/test/fts5faultG.test new file mode 100644 index 0000000000..bdcc153ad2 --- /dev/null +++ b/ext/fts5/test/fts5faultG.test @@ -0,0 +1,50 @@ +# 2010 June 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] fts5_common.tcl] +source $testdir/malloc_common.tcl +set testprefix fts5faultG + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +set ::testprefix fts5faultG + + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a); + INSERT INTO t1 VALUES('test renaming the table'); + INSERT INTO t1 VALUES(' after it has been written'); + INSERT INTO t1 VALUES(' actually other stuff instead'); +} +faultsim_save_and_close +do_faultsim_test 1 -faults oom* -prep { + faultsim_restore_and_reopen + execsql { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + } +} -body { + execsql { + DELETE FROM t1; + } +} -test { + catchsql { COMMIT } + faultsim_integrity_check + faultsim_test_result {0 {}} +} + + +finish_test diff --git a/ext/fts5/test/fts5savepoint.test b/ext/fts5/test/fts5savepoint.test index e431f9f5fd..1126222750 100644 --- a/ext/fts5/test/fts5savepoint.test +++ b/ext/fts5/test/fts5savepoint.test @@ -71,7 +71,7 @@ ifcapable fts3 { do_catchsql_test 3.2 { DROP TABLE vt1; - } {1 {SQL logic error}} + } {0 {}} do_execsql_test 3.3 { SAVEPOINT x; diff --git a/ext/fts5/test/fts5secure6.test b/ext/fts5/test/fts5secure6.test index ffb10cb24a..e2f4ceabc8 100644 --- a/ext/fts5/test/fts5secure6.test +++ b/ext/fts5/test/fts5secure6.test @@ -18,7 +18,7 @@ db progress 1 progress_handler set ::PHC 0 proc progress_handler {args} { incr ::PHC - if {($::PHC % 100000)==0} breakpoint + # if {($::PHC % 100000)==0} breakpoint return 0 } @@ -73,12 +73,12 @@ do_execsql_test 2.2 { #------------------------------------------------------------------------- reset_db -do_execsql_test 2.0 { +do_execsql_test 3.0 { CREATE VIRTUAL TABLE t1 USING fts5(x); INSERT INTO t1(t1, rank) VALUES('secure-delete', $sd) } -do_execsql_test 2.1 { +do_execsql_test 3.1 { BEGIN; INSERT INTO t1(rowid, x) VALUES(51869, 'when whenever where weress what turn'), @@ -91,5 +91,51 @@ do_execsql_test 3.2 { INSERT INTO t1(t1) VALUES('integrity-check'); } +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x); + INSERT INTO t1(rowid, x) VALUES(10, 'one two'); +} +do_execsql_test 4.1 { + UPDATE t1 SET x = 'one three' WHERE rowid=10; + INSERT INTO t1(t1, rank) VALUES('secure-delete', 1); +} +do_execsql_test 4.2 { + DELETE FROM t1 WHERE rowid=10; +} +do_execsql_test 4.3 { + INSERT INTO t1(t1) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE t1 USING fts5(content); + + INSERT INTO t1(t1,rank) VALUES('secure-delete',1); + INSERT INTO t1 VALUES('active'),('boomer'),('atom'),('atomic'), + ('alpha channel backup abandon test aback boomer atom alpha active'); + DELETE FROM t1 WHERE t1 MATCH 'abandon'; +} + +do_execsql_test 5.1 { + INSERT INTO t1(t1) VALUES('rebuild'); +} + +do_execsql_test 5.2 { + DELETE FROM t1 WHERE rowid NOTNULL<5; +} + +db close +sqlite3 db test.db + +do_execsql_test 5.3 { + PRAGMA integrity_check; +} {ok} + + finish_test diff --git a/ext/jni/GNUmakefile b/ext/jni/GNUmakefile index ddf97dd8ac..19a5080471 100644 --- a/ext/jni/GNUmakefile +++ b/ext/jni/GNUmakefile @@ -26,8 +26,9 @@ dir.src.c := $(dir.src)/c dir.bld := $(dir.jni)/bld dir.bld.c := $(dir.bld) dir.src.jni := $(dir.src)/org/sqlite/jni -dir.src.jni.tester := $(dir.src.jni)/tester +dir.src.capi := $(dir.src.jni)/capi dir.src.fts5 := $(dir.src.jni)/fts5 +dir.tests := $(dir.src)/tests mkdir ?= mkdir -p $(dir.bld.c): $(mkdir) $@ @@ -45,9 +46,9 @@ DISTCLEAN_FILES := $(dir.jni)/*~ $(dir.src.c)/*~ $(dir.src.jni)/*~ sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h .NOTPARALLEL: $(sqlite3-jni.h) -SQLite3Jni.java := src/org/sqlite/jni/SQLite3Jni.java -SQLTester.java := src/org/sqlite/jni/tester/SQLTester.java -SQLite3Jni.class := $(SQLite3Jni.java:.java=.class) +CApi.java := $(dir.src.capi)/CApi.java +SQLTester.java := $(dir.src.capi)/SQLTester.java +CApi.class := $(CApi.java:.java=.class) SQLTester.class := $(SQLTester.java:.java=.class) ######################################################################## @@ -61,8 +62,12 @@ SQLTester.class := $(SQLTester.java:.java=.class) # which the fts5 APIs have been stripped unless that feature is # intended to be stripped for good. enable.fts5 ?= 1 -# If enable.tester is 0, the org/sqlite/jni/tester/* bits are elided. -enable.tester ?= $(if $(wildcard $(dir.src.jni.tester)/SQLTester.java),1,0) + +ifeq (,$(wildcard $(dir.tests)/*)) + enable.tester := 0 +else + enable.tester := 1 +endif # bin.version-info = binary to output various sqlite3 version info # building the distribution zip file. @@ -73,10 +78,10 @@ $(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile # Be explicit about which Java files to compile so that we can work on # in-progress files without requiring them to be in a compilable statae. -JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\ - annotation/Canonical.java \ - annotation/NotNull.java \ - annotation/Nullable.java \ +JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/annotation/%,\ + NotNull.java \ + Nullable.java \ +) $(patsubst %,$(dir.src.capi)/%,\ AbstractCollationCallback.java \ AggregateFunction.java \ AuthorizerCallback.java \ @@ -97,21 +102,34 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\ ScalarFunction.java \ SQLFunction.java \ CallbackProxy.java \ - SQLite3Jni.java \ + CApi.java \ TableColumnMetadata.java \ TraceV2Callback.java \ UpdateHookCallback.java \ + ValueHolder.java \ WindowFunction.java \ XDestroyCallback.java \ sqlite3.java \ sqlite3_context.java \ sqlite3_stmt.java \ sqlite3_value.java \ +) $(patsubst %,$(dir.src.jni)/wrapper1/%,\ + AggregateFunction.java \ + ScalarFunction.java \ + SqlFunction.java \ + Sqlite.java \ + SqliteException.java \ + ValueHolder.java \ ) + JAVA_FILES.unittest := $(patsubst %,$(dir.src.jni)/%,\ - Tester1.java \ + capi/Tester1.java \ + wrapper1/Tester2.java \ ) ifeq (1,$(enable.fts5)) + JAVA_FILES.unittest += $(patsubst %,$(dir.src.fts5)/%,\ + TesterFts5.java \ + ) JAVA_FILES.main += $(patsubst %,$(dir.src.fts5)/%,\ fts5_api.java \ fts5_extension_function.java \ @@ -121,11 +139,10 @@ ifeq (1,$(enable.fts5)) Fts5ExtensionApi.java \ Fts5PhraseIter.java \ Fts5Tokenizer.java \ - TesterFts5.java \ XTokenizeCallback.java \ ) endif -JAVA_FILES.tester := $(dir.src.jni.tester)/SQLTester.java +JAVA_FILES.tester := $(SQLTester.java) JAVA_FILES.package.info := \ $(dir.src.jni)/package-info.java \ $(dir.src.jni)/annotation/package-info.java @@ -188,7 +205,19 @@ opt.fatal-oom ?= 1 opt.debug ?= 1 opt.metrics ?= 1 SQLITE_OPT = \ - -DSQLITE_ENABLE_RTREE \ + -DSQLITE_THREADSAFE=$(opt.threadsafe) \ + -DSQLITE_TEMP_STORE=2 \ + -DSQLITE_USE_URI=1 \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_OMIT_DEPRECATED \ + -DSQLITE_OMIT_SHARED_CACHE \ + -DSQLITE_C=$(sqlite3.c) \ + -DSQLITE_JNI_FATAL_OOM=$(opt.fatal-oom) \ + -DSQLITE_JNI_ENABLE_METRICS=$(opt.metrics) + +opt.extras ?= 1 +ifeq (1,$(opt.extras)) +SQLITE_OPT += -DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ -DSQLITE_ENABLE_STMTVTAB \ -DSQLITE_ENABLE_DBPAGE_VTAB \ @@ -196,21 +225,14 @@ SQLITE_OPT = \ -DSQLITE_ENABLE_BYTECODE_VTAB \ -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ -DSQLITE_ENABLE_PREUPDATE_HOOK \ - -DSQLITE_ENABLE_SQLLOG \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_OMIT_DEPRECATED \ - -DSQLITE_OMIT_SHARED_CACHE \ - -DSQLITE_THREADSAFE=$(opt.threadsafe) \ - -DSQLITE_TEMP_STORE=2 \ - -DSQLITE_USE_URI=1 \ - -DSQLITE_C=$(sqlite3.c) \ - -DSQLITE_JNI_FATAL_OOM=$(opt.fatal-oom) \ - -DSQLITE_JNI_ENABLE_METRICS=$(opt.metrics) + -DSQLITE_ENABLE_NORMALIZE \ + -DSQLITE_ENABLE_SQLLOG +endif ifeq (1,$(opt.debug)) SQLITE_OPT += -DSQLITE_DEBUG -g -DDEBUG -UNDEBUG else - SQLITE_OPT += -O2 + SQLITE_OPT += -Os endif ifeq (1,$(enable.fts5)) @@ -232,19 +254,18 @@ $$(dir.bld.c)/org_sqlite_jni$(3)_$(2).h: $(1)/$(2).java endef # Invoke ADD_JNI_H once for each Java file which includes JNI # declarations: -$(eval $(call ADD_JNI_H,$(dir.src.jni),SQLite3Jni,)) +$(eval $(call ADD_JNI_H,$(dir.src.capi),CApi,_capi)) +$(eval $(call ADD_JNI_H,$(dir.src.capi),SQLTester,_capi)) ifeq (1,$(enable.fts5)) $(eval $(call ADD_JNI_H,$(dir.src.fts5),Fts5ExtensionApi,_fts5)) $(eval $(call ADD_JNI_H,$(dir.src.fts5),fts5_api,_fts5)) $(eval $(call ADD_JNI_H,$(dir.src.fts5),fts5_tokenizer,_fts5)) endif -ifeq (1,$(enable.tester)) - $(eval $(call ADD_JNI_H,$(dir.src.jni.tester),SQLTester,_tester)) -endif $(sqlite3-jni.h.in): $(dir.bld.c) #package.dll.cfiles := package.dll.cflags = \ + -std=c99 \ -fPIC \ -I. \ -I$(dir $(sqlite3.h)) \ @@ -252,17 +273,18 @@ package.dll.cflags = \ -I$(JDK_HOME)/include \ $(patsubst %,-I%,$(patsubst %.h,,$(wildcard $(JDK_HOME)/include/*))) \ -Wall -# Using (-Wall -Wextra) triggers an untennable number of -# gcc warnings from sqlite3.c for mundane things like -# unused parameters. -# # The gross $(patsubst...) above is to include the platform-specific # subdir which lives under $(JDK_HOME)/include and is a required # include path for client-level code. +# +# Using (-Wall -Wextra) triggers an untennable number of +# gcc warnings from sqlite3.c for mundane things like +# unused parameters. ######################################################################## ifeq (1,$(enable.tester)) package.dll.cflags += -DSQLITE_JNI_ENABLE_SQLTester endif + $(sqlite3-jni.h): $(sqlite3-jni.h.in) $(MAKEFILE) @cat $(sqlite3-jni.h.in) > $@.tmp @if cmp $@ $@.tmp >/dev/null; then \ @@ -284,19 +306,23 @@ $(package.dll): $(sqlite3-jni.c) $(MAKEFILE) all: $(package.dll) .PHONY: test test-one -test.flags ?= -test.main.flags = -ea -Djava.library.path=$(dir.bld.c) \ - $(java.flags) -cp $(classpath) \ - org.sqlite.jni.Tester1 +Tester1.flags ?= +Tester2.flags ?= +test.flags.jvm = -ea -Djava.library.path=$(dir.bld.c) \ + $(java.flags) -cp $(classpath) test.deps := $(CLASS_FILES) $(package.dll) test-one: $(test.deps) - $(bin.java) $(test.main.flags) $(test.flags) + $(bin.java) $(test.flags.jvm) org.sqlite.jni.capi.Tester1 $(Tester1.flags) + $(bin.java) $(test.flags.jvm) org.sqlite.jni.wrapper1.Tester2 $(Tester2.flags) test-sqllog: $(test.deps) @echo "Testing with -sqllog..." - $(bin.java) $(test.main.flags) -sqllog + $(bin.java) $(test.flags.jvm) -sqllog test-mt: $(test.deps) @echo "Testing in multi-threaded mode:"; - $(bin.java) $(test.main.flags) -t 7 -r 50 -shuffle $(test.flags) + $(bin.java) $(test.flags.jvm) org.sqlite.jni.capi.Tester1 \ + -t 7 -r 50 -shuffle $(Tester1.flags) + $(bin.java) $(test.flags.jvm) org.sqlite.jni.wrapper1.Tester2 \ + -t 7 -r 50 -shuffle $(Tester2.flags) test: test-one test-mt tests: test test-sqllog @@ -308,21 +334,21 @@ ifeq (1,$(enable.tester)) tester-local: $(CLASS_FILES.tester) $(package.dll) $(bin.java) -ea -Djava.library.path=$(dir.bld.c) \ $(java.flags) -cp $(classpath) \ - org.sqlite.jni.tester.SQLTester $(tester.flags) $(tester.scripts) + org.sqlite.jni.capi.SQLTester $(tester.flags) $(tester.scripts) tester: tester-local else tester: - @echo "SQLTester support is disabled. Build with enable.tester=1 to enable it." + @echo "SQLTester support is disabled." endif -tester.extdir.default := src/tests/ext +tester.extdir.default := $(dir.tests)/ext tester.extdir ?= $(tester.extdir.default) tester.extern-scripts := $(wildcard $(tester.extdir)/*.test) ifneq (,$(tester.extern-scripts)) tester-ext: $(bin.java) -ea -Djava.library.path=$(dir.bld.c) \ $(java.flags) -cp $(classpath) \ - org.sqlite.jni.tester.SQLTester $(tester.flags) $(tester.extern-scripts) + org.sqlite.jni.capi.SQLTester $(tester.flags) $(tester.extern-scripts) else tester-ext: @echo "******************************************************"; \ @@ -362,13 +388,12 @@ JAVA_FILES.jar := $(JAVA_FILES.main) $(JAVA_FILES.unittest) $(JAVA_FILES.package CLASS_FILES.jar := $(filter-out %/package-info.class,$(JAVA_FILES.jar:.java=.class)) $(package.jar.in): $(package.dll) $(MAKEFILE) ls -1 \ - $(dir.src.jni)/*.java $(dir.src.jni)/*.class \ - $(dir.src.jni)/annotation/*.java $(dir.src.jni)/annotation/*.class \ + $(dir.src.jni)/*/*.java $(dir.src.jni)/*/*.class \ | sed -e 's,^$(dir.src)/,,' | sort > $@ $(package.jar): $(CLASS_FILES.jar) $(MAKEFILE) $(package.jar.in) @rm -f $(dir.src)/c/*~ $(dir.src.jni)/*~ - cd $(dir.src); $(bin.jar) -cfe ../$@ org.sqlite.jni.Tester1 @$(package.jar.in) + cd $(dir.src); $(bin.jar) -cfe ../$@ org.sqlite.jni.capi.Tester1 @$(package.jar.in) @ls -la $@ @echo "To use this jar you will need the -Djava.library.path=DIR/CONTAINING/libsqlite3-jni.so flag." @echo "e.g. java -Djava.library.path=bld -jar $@" @@ -381,11 +406,12 @@ run-jar: $(package.jar) $(package.dll) # javadoc... dir.doc := $(dir.jni)/javadoc doc.index := $(dir.doc)/index.html -javadoc.exclude := -exclude org.sqlite.jni.tester \ - -exclude org.sqlite.jni.fts5 +javadoc.exclude := -exclude org.sqlite.jni.fts5 # ^^^^ 2023-09-13: elide the fts5 parts from the public docs for # the time being, as it's not clear where the Java bindings for # those bits are going. +# javadoc.exclude += -exclude org.sqlite.jni.capi +# ^^^^ exclude the capi API only for certain builds (TBD) $(doc.index): $(JAVA_FILES.main) $(MAKEFILE) @if [ -d $(dir.doc) ]; then rm -fr $(dir.doc)/*; fi $(bin.javadoc) -cp $(classpath) -d $(dir.doc) -quiet \ @@ -406,7 +432,7 @@ docserve: $(doc.index) # Clean up... CLEAN_FILES += $(dir.bld.c)/* \ $(dir.src.jni)/*.class \ - $(dir.src.jni.tester)/*.class \ + $(dir.src.jni)/*/*.class \ $(package.dll) \ hs_err_pid*.log diff --git a/ext/jni/README.md b/ext/jni/README.md index dfef061bcd..f2811fddb2 100644 --- a/ext/jni/README.md +++ b/ext/jni/README.md @@ -55,7 +55,7 @@ Hello World ```java import org.sqlite.jni.*; -import static org.sqlite.jni.SQLite3Jni.*; +import static org.sqlite.jni.CApi.*; ... diff --git a/ext/jni/src/c/sqlite3-jni.c b/ext/jni/src/c/sqlite3-jni.c index c9ee75cb9b..245ce4f9e9 100644 --- a/ext/jni/src/c/sqlite3-jni.c +++ b/ext/jni/src/c/sqlite3-jni.c @@ -10,7 +10,7 @@ ** ************************************************************************* ** This file implements the JNI bindings declared in -** org.sqlite.jni.SQLiteJni (from which sqlite3-jni.h is generated). +** org.sqlite.jni.capi.CApi (from which sqlite3-jni.h is generated). */ /* @@ -43,6 +43,14 @@ /**********************************************************************/ /* SQLITE_ENABLE_... */ +/* +** Unconditionally enable API_ARMOR in the JNI build. It ensures that +** public APIs behave predictable in the face of passing illegal NULLs +** or ranges which might otherwise invoke undefined behavior. +*/ +#undef SQLITE_ENABLE_API_ARMOR +#define SQLITE_ENABLE_API_ARMOR 1 + #ifndef SQLITE_ENABLE_BYTECODE_VTAB # define SQLITE_ENABLE_BYTECODE_VTAB 1 #endif @@ -147,6 +155,7 @@ #include "sqlite3-jni.h" #include #include /* only for testing/debugging */ +#include /* intptr_t for 32-bit builds */ /* Only for debugging */ #define MARKER(pfexp) \ @@ -160,7 +169,7 @@ ** prefix seen in this macro. */ #define JniFuncName(Suffix) \ - Java_org_sqlite_jni_SQLite3Jni_sqlite3_ ## Suffix + Java_org_sqlite_jni_capi_CApi_sqlite3_ ## Suffix /* Prologue for JNI function declarations and definitions. */ #define JniDecl(ReturnType,Suffix) \ @@ -174,6 +183,18 @@ */ #define S3JniApi(CFunc,ReturnType,Suffix) JniDecl(ReturnType,Suffix) +/* +** S3JniCast_L2P and P2L cast jlong (64-bit) to/from pointers. This is +** required for casting warning-free on 32-bit builds, where we +** otherwise get complaints that we're casting between different-sized +** int types. +** +** This use of intptr_t is the _only_ reason we require +** which, in turn, requires building with -std=c99 (or later). +*/ +#define S3JniCast_L2P(JLongAsPtr) (void*)((intptr_t)(JLongAsPtr)) +#define S3JniCast_P2L(PTR) (jlong)((intptr_t)(PTR)) + /* ** Shortcuts for the first 2 parameters to all JNI bindings. ** @@ -365,26 +386,26 @@ static const struct { #define RefN(INDEX, KLAZZ) MkRef(INDEX, KLAZZ, "nativePointer", "J") /* OutputPointer.T ref */ #define RefO(INDEX, KLAZZ, SIG) MkRef(INDEX, KLAZZ, "value", SIG) - RefN(0, "sqlite3"), - RefN(1, "sqlite3_backup"), - RefN(2, "sqlite3_blob"), - RefN(3, "sqlite3_context"), - RefN(4, "sqlite3_stmt"), - RefN(5, "sqlite3_value"), - RefO(6, "OutputPointer$Bool", "Z"), - RefO(7, "OutputPointer$Int32", "I"), - RefO(8, "OutputPointer$Int64", "J"), - RefO(9, "OutputPointer$sqlite3", - "Lorg/sqlite/jni/sqlite3;"), - RefO(10, "OutputPointer$sqlite3_blob", - "Lorg/sqlite/jni/sqlite3_blob;"), - RefO(11, "OutputPointer$sqlite3_stmt", - "Lorg/sqlite/jni/sqlite3_stmt;"), - RefO(12, "OutputPointer$sqlite3_value", - "Lorg/sqlite/jni/sqlite3_value;"), - RefO(13, "OutputPointer$String", "Ljava/lang/String;"), + RefN(0, "capi/sqlite3"), + RefN(1, "capi/sqlite3_backup"), + RefN(2, "capi/sqlite3_blob"), + RefN(3, "capi/sqlite3_context"), + RefN(4, "capi/sqlite3_stmt"), + RefN(5, "capi/sqlite3_value"), + RefO(6, "capi/OutputPointer$Bool", "Z"), + RefO(7, "capi/OutputPointer$Int32", "I"), + RefO(8, "capi/OutputPointer$Int64", "J"), + RefO(9, "capi/OutputPointer$sqlite3", + "Lorg/sqlite/jni/capi/sqlite3;"), + RefO(10, "capi/OutputPointer$sqlite3_blob", + "Lorg/sqlite/jni/capi/sqlite3_blob;"), + RefO(11, "capi/OutputPointer$sqlite3_stmt", + "Lorg/sqlite/jni/capi/sqlite3_stmt;"), + RefO(12, "capi/OutputPointer$sqlite3_value", + "Lorg/sqlite/jni/capi/sqlite3_value;"), + RefO(13, "capi/OutputPointer$String", "Ljava/lang/String;"), #ifdef SQLITE_ENABLE_FTS5 - RefO(14, "OutputPointer$ByteArray", "[B"), + RefO(14, "capi/OutputPointer$ByteArray", "[B"), RefN(15, "fts5/Fts5Context"), RefN(16, "fts5/Fts5ExtensionApi"), RefN(17, "fts5/fts5_api"), @@ -639,7 +660,7 @@ struct S3JniGlobalType { } g; /* ** The list of Java-side auto-extensions - ** (org.sqlite.jni.AutoExtensionCallback objects). + ** (org.sqlite.jni.capi.AutoExtensionCallback objects). */ struct { S3JniAutoExtension *aExt /* The auto-extension list. It is @@ -811,22 +832,32 @@ static void s3jni_incr( volatile unsigned int * const p ){ #endif /* Helpers for jstring and jbyteArray. */ -static const char * s3jni__jstring_to_mutf8_bytes(JNIEnv * const env, jstring v ){ +static const char * s3jni__jstring_to_mutf8(JNIEnv * const env, jstring v ){ const char *z = v ? (*env)->GetStringUTFChars(env, v, NULL) : 0; s3jni_oom_check( v ? !!z : !z ); return z; } -#define s3jni_jstring_to_mutf8(ARG) s3jni__jstring_to_mutf8_bytes(env, (ARG)) +#define s3jni_jstring_to_mutf8(ARG) s3jni__jstring_to_mutf8(env, (ARG)) #define s3jni_mutf8_release(ARG,VAR) if( VAR ) (*env)->ReleaseStringUTFChars(env, ARG, VAR) -static jbyte * s3jni__jbyteArray_bytes(JNIEnv * const env, jbyteArray jBA ){ +/* +** If jBA is not NULL then its GetByteArrayElements() value is +** returned. If jBA is not NULL and nBA is not NULL then *nBA is set +** to the GetArrayLength() of jBA. If GetByteArrayElements() requires +** an allocation and that allocation fails then this function either +** fails fatally or returns 0, depending on build-time options. + */ +static jbyte * s3jni__jbyteArray_bytes2(JNIEnv * const env, jbyteArray jBA, jsize * nBA ){ jbyte * const rv = jBA ? (*env)->GetByteArrayElements(env, jBA, NULL) : 0; s3jni_oom_check( jBA ? !!rv : 1 ); + if( jBA && nBA ) *nBA = (*env)->GetArrayLength(env, jBA); return rv; } -#define s3jni_jbyteArray_bytes(jByteArray) s3jni__jbyteArray_bytes(env, (jByteArray)) +#define s3jni_jbyteArray_bytes2(jByteArray,ptrToSz) \ + s3jni__jbyteArray_bytes2(env, (jByteArray), (ptrToSz)) +#define s3jni_jbyteArray_bytes(jByteArray) s3jni__jbyteArray_bytes2(env, (jByteArray), 0) #define s3jni_jbyteArray_release(jByteArray,jBytes) \ if( jBytes ) (*env)->ReleaseByteArrayElements(env, jByteArray, jBytes, JNI_ABORT) #define s3jni_jbyteArray_commit(jByteArray,jBytes) \ @@ -888,7 +919,7 @@ static S3JniEnv * S3JniEnv__get(JNIEnv * const env){ ** ** For purposes of certain hand-crafted JNI function bindings, we ** need a way of reporting errors which is consistent with the rest of -** the C API, as opposed to throwing JS exceptions. To that end, this +** the C API, as opposed to throwing Java exceptions. To that end, this ** internal-use-only function is a thin proxy around ** sqlite3ErrorWithMessage(). The intent is that it only be used from ** JNI bindings such as sqlite3_prepare_v2/v3(), and definitely not @@ -951,6 +982,7 @@ static jstring s3jni__utf8_to_jstring(JNIEnv * const env, hypothetically do this for any strings where n<4 and z is NUL-terminated and none of z[0..3] are NUL bytes. */ rv = (*env)->NewStringUTF(env, ""); + s3jni_oom_check( rv ); }else if( z ){ jbyteArray jba; if( n<0 ) n = sqlite3Strlen30(z); @@ -964,8 +996,8 @@ static jstring s3jni__utf8_to_jstring(JNIEnv * const env, } S3JniUnrefLocal(jba); } + s3jni_oom_check( rv ); } - s3jni_oom_check( rv ); return rv; } #define s3jni_utf8_to_jstring(CStr,n) s3jni__utf8_to_jstring(env, CStr, n) @@ -988,7 +1020,7 @@ static jstring s3jni__utf8_to_jstring(JNIEnv * const env, static char * s3jni__jstring_to_utf8(JNIEnv * const env, jstring jstr, int *nLen){ jbyteArray jba; - jsize nBa; + jsize nBA; char *rv; if( !jstr ) return 0; @@ -1002,12 +1034,12 @@ static char * s3jni__jstring_to_utf8(JNIEnv * const env, if( nLen ) *nLen = 0; return 0; } - nBa = (*env)->GetArrayLength(env, jba); - if( nLen ) *nLen = (int)nBa; - rv = s3jni_malloc( nBa + 1 ); + nBA = (*env)->GetArrayLength(env, jba); + if( nLen ) *nLen = (int)nBA; + rv = s3jni_malloc( nBA + 1 ); if( rv ){ - (*env)->GetByteArrayRegion(env, jba, 0, nBa, (jbyte*)rv); - rv[nBa] = 0; + (*env)->GetByteArrayRegion(env, jba, 0, nBA, (jbyte*)rv); + rv[nBA] = 0; } S3JniUnrefLocal(jba); return rv; @@ -1176,6 +1208,8 @@ static void S3JniHook__unref(JNIEnv * const env, S3JniHook * const s){ } S3JniUnrefGlobal(s->jObj); S3JniUnrefGlobal(s->jExtra); + }else{ + assert( !s->jExtra ); } *s = S3JniHook_empty; } @@ -1183,8 +1217,8 @@ static void S3JniHook__unref(JNIEnv * const env, S3JniHook * const s){ /* ** Allocates one blank S3JniHook object from the recycling bin, if -** available, else from the heap. Returns NULL or dies on OOM. Locks -** the global mutex. +** available, else from the heap. Returns NULL or dies on OOM, +** depending on build options. Locks on SJG.hooks.mutex. */ static S3JniHook *S3JniHook__alloc(JNIEnv * const env){ S3JniHook * p = 0; @@ -1211,7 +1245,7 @@ static S3JniHook *S3JniHook__alloc(JNIEnv * const env){ /* ** The rightful fate of all results from S3JniHook_alloc(). Locks on -** SJG>hooks.mutex. +** SJG.hook.mutex. */ static void S3JniHook__free(JNIEnv * const env, S3JniHook * const p){ if(p){ @@ -1290,10 +1324,11 @@ static void S3JniDb__set_aside(JNIEnv * const env, S3JniDb * const s){ /* ** Uncache any state for the given JNIEnv, clearing all Java ** references the cache owns. Returns true if env was cached and false -** if it was not found in the cache. Ownership of the given object is -** passed over to this function, which makes it free for re-use. +** if it was not found in the cache. Ownership of the S3JniEnv object +** associated with the given argument is transferred to this function, +** which makes it free for re-use. ** -** Requires that the Env mutex be locked. +** Requires that the env mutex be locked. */ static int S3JniEnv_uncache(JNIEnv * const env){ struct S3JniEnv * row; @@ -1307,7 +1342,7 @@ static int S3JniEnv_uncache(JNIEnv * const env){ } } if( !row ){ - return 0; + return 0; } if( pPrev) pPrev->pNext = row->pNext; else{ @@ -1346,6 +1381,7 @@ static S3JniNphOp * s3jni__nphop(JNIEnv * const env, S3JniNphOp const* pRef){ S3JniNph_mutex_enter; if( !pNC->klazz ){ jclass const klazz = (*env)->FindClass(env, pRef->zName); + //printf("FindClass %s\n", pRef->zName); S3JniExceptionIsFatal("FindClass() unexpectedly threw"); pNC->klazz = S3JniRefGlobal(klazz); } @@ -1394,7 +1430,8 @@ static jfieldID s3jni_nphop_field(JNIEnv * const env, S3JniNphOp const* pRef){ static void NativePointerHolder__set(JNIEnv * const env, S3JniNphOp const* pRef, jobject jNph, const void * p){ assert( jNph ); - (*env)->SetLongField(env, jNph, s3jni_nphop_field(env, pRef), (jlong)p); + (*env)->SetLongField(env, jNph, s3jni_nphop_field(env, pRef), + S3JniCast_P2L(p)); S3JniExceptionIsFatal("Could not set NativePointerHolder.nativePointer."); } @@ -1410,7 +1447,9 @@ static void * NativePointerHolder__get(JNIEnv * env, jobject jNph, S3JniNphOp const* pRef){ void * rv = 0; if( jNph ){ - rv = (void*)(*env)->GetLongField(env, jNph, s3jni_nphop_field(env, pRef)); + rv = S3JniCast_L2P( + (*env)->GetLongField(env, jNph, s3jni_nphop_field(env, pRef)) + ); S3JniExceptionIsFatal("Cannot fetch NativePointerHolder.nativePointer."); } return rv; @@ -1440,29 +1479,28 @@ static void * NativePointerHolder__get(JNIEnv * env, jobject jNph, #define PtrGet_sqlite3_context(OBJ) PtrGet_T(sqlite3_context, OBJ) #define PtrGet_sqlite3_stmt(OBJ) PtrGet_T(sqlite3_stmt, OBJ) #define PtrGet_sqlite3_value(OBJ) PtrGet_T(sqlite3_value, OBJ) - -#if 0 /* -** Enters the S3JniDb mutex and PtrGet_sqlite3()'s jObj. If that's -** NULL then it leaves the mutex, else the mutex is still entered -** when this returns and the caller is obligated to leave it. +** S3JniLongPtr_T(X,Y) expects X to be an unqualified sqlite3 struct +** type name and Y to be a native pointer to such an object in the +** form of a jlong value. The jlong is simply cast to (X*). This +** approach is, as of 2023-09-27, supplanting the former approach. We +** now do the native pointer extraction in the Java side, rather than +** the C side, because it's reportedly significantly faster. The +** intptr_t part here is necessary for compatibility with (at least) +** ARM32. */ -static sqlite3* PtrGet__sqlite3_lock(JNIEnv * const env, jobject jObj){ - sqlite3 *rv; - S3JniDb_mutex_enter; - rv = PtrGet_sqlite3(jObj); - if( !rv ){ S3JniDb_mutex_leave; } - return rv; -} -#undef PtrGet_sqlite3 -#define PtrGet_sqlite3(JOBJ) PtrGet__sqlite3_lock(env, (JOBJ)) -#endif - +#define S3JniLongPtr_T(T,JLongAsPtr) (T*)((intptr_t)(JLongAsPtr)) +#define S3JniLongPtr_sqlite3(JLongAsPtr) S3JniLongPtr_T(sqlite3,JLongAsPtr) +#define S3JniLongPtr_sqlite3_backup(JLongAsPtr) S3JniLongPtr_T(sqlite3_backup,JLongAsPtr) +#define S3JniLongPtr_sqlite3_blob(JLongAsPtr) S3JniLongPtr_T(sqlite3_blob,JLongAsPtr) +#define S3JniLongPtr_sqlite3_stmt(JLongAsPtr) S3JniLongPtr_T(sqlite3_stmt,JLongAsPtr) +#define S3JniLongPtr_sqlite3_value(JLongAsPtr) S3JniLongPtr_T(sqlite3_value,JLongAsPtr) /* ** Extracts the new S3JniDb instance from the free-list, or allocates -** one if needed, associats it with pDb, and returns. Returns NULL on -** OOM. pDb MUST, on success of the calling operation, subsequently be -** associated with jDb via NativePointerHolder_set(). +** one if needed, associates it with pDb, and returns. Returns NULL +** on OOM. The returned object MUST, on success of the calling +** operation, subsequently be associated with jDb via +** NativePointerHolder_set() or freed using S3JniDb_set_aside(). */ static S3JniDb * S3JniDb_alloc(JNIEnv * const env, jobject jDb){ S3JniDb * rv = 0; @@ -1475,7 +1513,7 @@ static S3JniDb * S3JniDb_alloc(JNIEnv * const env, jobject jDb){ } S3JniDb_mutex_leave; if( 0==rv ){ - rv = s3jni_malloc( sizeof(S3JniDb)); + rv = s3jni_malloc(sizeof(S3JniDb)); if( rv ){ s3jni_incr( &SJG.metrics.nPdbAlloc ); } @@ -1488,7 +1526,7 @@ static S3JniDb * S3JniDb_alloc(JNIEnv * const env, jobject jDb){ } /* -** Returns the S3JniDb object for the given org.sqlite.jni.sqlite3 +** Returns the S3JniDb object for the given org.sqlite.jni.capi.sqlite3 ** object, or NULL if jDb is NULL, no pointer can be extracted ** from it, or no matching entry can be found. */ @@ -1514,6 +1552,8 @@ static void S3JniDb_xDestroy(void *p){ */ #define S3JniDb_from_c(sqlite3Ptr) \ ((sqlite3Ptr) ? S3JniDb_from_clientdata(sqlite3Ptr) : 0) +#define S3JniDb_from_jlong(sqlite3PtrAsLong) \ + S3JniDb_from_c(S3JniLongPtr_T(sqlite3,sqlite3PtrAsLong)) /* ** Unref any Java-side state in (S3JniAutoExtension*) AX and zero out @@ -1535,7 +1575,7 @@ static int S3JniAutoExtension_init(JNIEnv *const env, S3JniAutoExt_mutex_assertLocker; *ax = S3JniHook_empty; ax->midCallback = (*env)->GetMethodID(env, klazz, "call", - "(Lorg/sqlite/jni/sqlite3;)I"); + "(Lorg/sqlite/jni/capi/sqlite3;)I"); S3JniUnrefLocal(klazz); S3JniExceptionWarnIgnore; if( !ax->midCallback ){ @@ -1631,7 +1671,7 @@ static int encodingTypeIsValid(int eTextRep){ } /* For use with sqlite3_result/value_pointer() */ -static const char * const ResultJavaValuePtrStr = "org.sqlite.jni.ResultJavaVal"; +static const char * const ResultJavaValuePtrStr = "org.sqlite.jni.capi.ResultJavaVal"; /* ** If v is not NULL, it must be a jobject global reference. Its @@ -1729,9 +1769,9 @@ static S3JniUdf * S3JniUdf_alloc(JNIEnv * const env, jobject jObj){ } if( s ){ const char * zFSI = /* signature for xFunc, xStep, xInverse */ - "(Lorg/sqlite/jni/sqlite3_context;[Lorg/sqlite/jni/sqlite3_value;)V"; + "(Lorg/sqlite/jni/capi/sqlite3_context;[Lorg/sqlite/jni/capi/sqlite3_value;)V"; const char * zFV = /* signature for xFinal, xValue */ - "(Lorg/sqlite/jni/sqlite3_context;)V"; + "(Lorg/sqlite/jni/capi/sqlite3_context;)V"; jclass const klazz = (*env)->GetObjectClass(env, jObj); memset(s, 0, sizeof(*s)); @@ -1805,8 +1845,8 @@ typedef struct { ** UDF, writing the result (Java wrappers for cx and argv) in the ** final 2 arguments. Returns 0 on success, SQLITE_NOMEM on allocation ** error. On error *jCx and *jArgv will be set to 0. The output -** objects are of type org.sqlite.jni.sqlite3_context and -** array-of-org.sqlite3.jni.sqlite3_value, respectively. +** objects are of type org.sqlite.jni.capi.sqlite3_context and +** array-of-org.sqlite.jni.capi.sqlite3_value, respectively. */ static int udf_args(JNIEnv *env, sqlite3_context * const cx, @@ -1838,6 +1878,28 @@ error_oom: return SQLITE_NOMEM; } +/* +** Requires that jCx and jArgv are sqlite3_context +** resp. array-of-sqlite3_value values initialized by udf_args(). This +** function zeroes out the nativePointer member of jCx and each entry +** in jArgv. This is a safety-net precaution to avoid undefined +** behavior if a Java-side UDF holds a reference to one of its +** arguments. This MUST be called from any function which successfully +** calls udf_args(), after calling the corresponding UDF and checking +** its exception status. It MUST NOT be called in any other case. +*/ +static void udf_unargs(JNIEnv *env, jobject jCx, int argc, jobjectArray jArgv){ + int i = 0; + assert(jCx); + NativePointerHolder_set(S3JniNph(sqlite3_context), jCx, 0); + for( ; i < argc; ++i ){ + jobject jsv = (*env)->GetObjectArrayElement(env, jArgv, i); + assert(jsv); + NativePointerHolder_set(S3JniNph(sqlite3_value), jsv, 0); + } +} + + /* ** Must be called immediately after a Java-side UDF callback throws. ** If translateToErr is true then it sets the exception's message in @@ -1897,6 +1959,7 @@ static int udf_xFSI(sqlite3_context* const pCx, int argc, rc = udf_report_exception(env, 'F'==zFuncType[1]/*xFunc*/, pCx, s->zFuncName, zFuncType); } + udf_unargs(env, args.jcx, argc, args.jargv); } S3JniUnrefLocal(args.jcx); S3JniUnrefLocal(args.jargv); @@ -1992,51 +2055,63 @@ static void udf_xInverse(sqlite3_context* cx, int argc, return rv; \ } /** Create a trivial JNI wrapper for (int CName(sqlite3_stmt*)). */ -#define WRAP_INT_STMT(JniNameSuffix,CName) \ - JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jobject jpStmt){ \ - jint const rc = (jint)CName(PtrGet_sqlite3_stmt(jpStmt)); \ - S3JniExceptionIgnore /* squelch -Xcheck:jni */; \ - return rc; \ +#define WRAP_INT_STMT(JniNameSuffix,CName) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpStmt){ \ + return (jint)CName(S3JniLongPtr_sqlite3_stmt(jpStmt)); \ } /** Create a trivial JNI wrapper for (int CName(sqlite3_stmt*,int)). */ #define WRAP_INT_STMT_INT(JniNameSuffix,CName) \ - JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jobject pStmt, jint n){ \ - return (jint)CName(PtrGet_sqlite3_stmt(pStmt), (int)n); \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpStmt, jint n){ \ + return (jint)CName(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)n); \ } -/** Create a trivial JNI wrapper for (boolish-int CName(sqlite3_stmt*)). */ -#define WRAP_BOOL_STMT(JniNameSuffix,CName) \ - JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jobject pStmt){ \ - return CName(PtrGet_sqlite3_stmt(pStmt)) ? JNI_TRUE : JNI_FALSE; \ +/** Create a trivial JNI wrapper for (boolean CName(sqlite3_stmt*)). */ +#define WRAP_BOOL_STMT(JniNameSuffix,CName) \ + JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jobject jStmt){ \ + return CName(PtrGet_sqlite3_stmt(jStmt)) ? JNI_TRUE : JNI_FALSE; \ } /** Create a trivial JNI wrapper for (jstring CName(sqlite3_stmt*,int)). */ -#define WRAP_STR_STMT_INT(JniNameSuffix,CName) \ - JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass, jobject pStmt, jint ndx){ \ +#define WRAP_STR_STMT_INT(JniNameSuffix,CName) \ + JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass, jlong jpStmt, jint ndx){ \ return s3jni_utf8_to_jstring( \ - CName(PtrGet_sqlite3_stmt(pStmt), (int)ndx), \ - -1); \ - } -/** Create a trivial JNI wrapper for (int CName(sqlite3*)). */ -#define WRAP_INT_DB(JniNameSuffix,CName) \ - JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jobject pDb){ \ - return (jint)CName(PtrGet_sqlite3(pDb)); \ + CName(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx), \ + -1); \ } /** Create a trivial JNI wrapper for (boolean CName(sqlite3*)). */ -#define WRAP_BOOL_DB(JniNameSuffix,CName) \ - JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jobject pDb){ \ - return CName(PtrGet_sqlite3(pDb)) ? JNI_TRUE : JNI_FALSE; \ +#define WRAP_BOOL_DB(JniNameSuffix,CName) \ + JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jlong jpDb){ \ + return CName(S3JniLongPtr_sqlite3(jpDb)) ? JNI_TRUE : JNI_FALSE; \ + } +/** Create a trivial JNI wrapper for (int CName(sqlite3*)). */ +#define WRAP_INT_DB(JniNameSuffix,CName) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpDb){ \ + return (jint)CName(S3JniLongPtr_sqlite3(jpDb)); \ } /** Create a trivial JNI wrapper for (int64 CName(sqlite3*)). */ -#define WRAP_INT64_DB(JniNameSuffix,CName) \ - JniDecl(jlong,JniNameSuffix)(JniArgsEnvClass, jobject pDb){ \ - return (jlong)CName(PtrGet_sqlite3(pDb)); \ +#define WRAP_INT64_DB(JniNameSuffix,CName) \ + JniDecl(jlong,JniNameSuffix)(JniArgsEnvClass, jlong jpDb){ \ + return (jlong)CName(S3JniLongPtr_sqlite3(jpDb)); \ + } +/** Create a trivial JNI wrapper for (jstring CName(sqlite3*,int)). */ +#define WRAP_STR_DB_INT(JniNameSuffix,CName) \ + JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass, jlong jpDb, jint ndx){ \ + return s3jni_utf8_to_jstring( \ + CName(S3JniLongPtr_sqlite3(jpDb), (int)ndx), \ + -1); \ } /** Create a trivial JNI wrapper for (int CName(sqlite3_value*)). */ -#define WRAP_INT_SVALUE(JniNameSuffix,CName) \ - JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jobject jpSValue){ \ - return (jint)CName(PtrGet_sqlite3_value(jpSValue)); \ +#define WRAP_INT_SVALUE(JniNameSuffix,CName,DfltOnNull) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpSValue){ \ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSValue); \ + return (jint)(sv ? CName(sv): DfltOnNull); \ + } +/** Create a trivial JNI wrapper for (boolean CName(sqlite3_value*)). */ +#define WRAP_BOOL_SVALUE(JniNameSuffix,CName,DfltOnNull) \ + JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jlong jpSValue){ \ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSValue); \ + return (jint)(sv ? CName(sv) : DfltOnNull) \ + ? JNI_TRUE : JNI_FALSE; \ } -WRAP_INT_STMT(1bind_1parameter_1count, sqlite3_bind_parameter_count) WRAP_INT_DB(1changes, sqlite3_changes) WRAP_INT64_DB(1changes64, sqlite3_changes64) WRAP_INT_STMT(1clear_1bindings, sqlite3_clear_bindings) @@ -2050,6 +2125,7 @@ WRAP_STR_STMT_INT(1column_1origin_1name, sqlite3_column_origin_name) WRAP_STR_STMT_INT(1column_1table_1name, sqlite3_column_table_name) WRAP_INT_STMT_INT(1column_1type, sqlite3_column_type) WRAP_INT_STMT(1data_1count, sqlite3_data_count) +WRAP_STR_DB_INT(1db_1name, sqlite3_db_name) WRAP_INT_DB(1error_1offset, sqlite3_error_offset) WRAP_INT_DB(1extended_1errcode, sqlite3_extended_errcode) WRAP_BOOL_DB(1get_1autocommit, sqlite3_get_autocommit) @@ -2064,6 +2140,7 @@ WRAP_INT_DB(1preupdate_1depth, sqlite3_preupdate_depth) WRAP_INT_INT(1release_1memory, sqlite3_release_memory) WRAP_INT_INT(1sleep, sqlite3_sleep) WRAP_MUTF8_VOID(1sourceid, sqlite3_sourceid) +WRAP_BOOL_STMT(1stmt_1busy, sqlite3_stmt_busy) WRAP_INT_STMT_INT(1stmt_1explain, sqlite3_stmt_explain) WRAP_INT_STMT(1stmt_1isexplain, sqlite3_stmt_isexplain) WRAP_BOOL_STMT(1stmt_1readonly, sqlite3_stmt_readonly) @@ -2071,16 +2148,16 @@ WRAP_INT_DB(1system_1errno, sqlite3_system_errno) WRAP_INT_VOID(1threadsafe, sqlite3_threadsafe) WRAP_INT_DB(1total_1changes, sqlite3_total_changes) WRAP_INT64_DB(1total_1changes64, sqlite3_total_changes64) -WRAP_INT_SVALUE(1value_1bytes, sqlite3_value_bytes) -WRAP_INT_SVALUE(1value_1bytes16, sqlite3_value_bytes16) -WRAP_INT_SVALUE(1value_1encoding, sqlite3_value_encoding) -WRAP_INT_SVALUE(1value_1frombind, sqlite3_value_frombind) -WRAP_INT_SVALUE(1value_1nochange, sqlite3_value_nochange) -WRAP_INT_SVALUE(1value_1numeric_1type, sqlite3_value_numeric_type) -WRAP_INT_SVALUE(1value_1subtype, sqlite3_value_subtype) -WRAP_INT_SVALUE(1value_1type, sqlite3_value_type) +WRAP_INT_SVALUE(1value_1encoding, sqlite3_value_encoding,SQLITE_UTF8) +WRAP_BOOL_SVALUE(1value_1frombind, sqlite3_value_frombind,0) +WRAP_INT_SVALUE(1value_1nochange, sqlite3_value_nochange,0) +WRAP_INT_SVALUE(1value_1numeric_1type, sqlite3_value_numeric_type,SQLITE_NULL) +WRAP_INT_SVALUE(1value_1subtype, sqlite3_value_subtype,0) +WRAP_INT_SVALUE(1value_1type, sqlite3_value_type,SQLITE_NULL) #undef WRAP_BOOL_DB +#undef WRAP_BOOL_STMT +#undef WRAP_BOOL_SVALUE #undef WRAP_INT64_DB #undef WRAP_INT_DB #undef WRAP_INT_INT @@ -2090,6 +2167,7 @@ WRAP_INT_SVALUE(1value_1type, sqlite3_value_type) #undef WRAP_INT_VOID #undef WRAP_MUTF8_VOID #undef WRAP_STR_STMT_INT +#undef WRAP_STR_DB_INT S3JniApi(sqlite3_aggregate_context(),jlong,1aggregate_1context)( JniArgsEnvClass, jobject jCx, jboolean initialize @@ -2100,7 +2178,7 @@ S3JniApi(sqlite3_aggregate_context(),jlong,1aggregate_1context)( ? (int)sizeof(void*) : 0)) : 0; - return (jlong)p; + return S3JniCast_P2L(p); } /* Central auto-extension handler. */ @@ -2236,19 +2314,21 @@ S3JniApi(sqlite3_auto_extension(),jint,1auto_1extension)( } S3JniApi(sqlite3_backup_finish(),jint,1backup_1finish)( - JniArgsEnvClass, jobject jBack + JniArgsEnvClass, jlong jpBack ){ - sqlite3_backup * const pB = PtrGet_sqlite3_backup(jBack); - NativePointerHolder_set(S3JniNph(sqlite3_backup), jBack, 0); - return sqlite3_backup_finish(pB); + int rc = 0; + if( jpBack!=0 ){ + rc = sqlite3_backup_finish( S3JniLongPtr_sqlite3_backup(jpBack) ); + } + return rc; } S3JniApi(sqlite3_backup_init(),jobject,1backup_1init)( - JniArgsEnvClass, jobject jDbDest, jstring jTDest, - jobject jDbSrc, jstring jTSrc + JniArgsEnvClass, jlong jpDbDest, jstring jTDest, + jlong jpDbSrc, jstring jTSrc ){ - sqlite3 * const pDest = PtrGet_sqlite3(jDbDest); - sqlite3 * const pSrc = PtrGet_sqlite3(jDbSrc); + sqlite3 * const pDest = S3JniLongPtr_sqlite3(jpDbDest); + sqlite3 * const pSrc = S3JniLongPtr_sqlite3(jpDbSrc); char * const zDest = s3jni_jstring_to_utf8(jTDest, 0); char * const zSrc = s3jni_jstring_to_utf8(jTSrc, 0); jobject rv = 0; @@ -2269,94 +2349,105 @@ S3JniApi(sqlite3_backup_init(),jobject,1backup_1init)( } S3JniApi(sqlite3_backup_pagecount(),jint,1backup_1pagecount)( - JniArgsEnvClass, jobject jBack + JniArgsEnvClass, jlong jpBack ){ - return sqlite3_backup_pagecount(PtrGet_sqlite3_backup(jBack)); + return sqlite3_backup_pagecount(S3JniLongPtr_sqlite3_backup(jpBack)); } S3JniApi(sqlite3_backup_remaining(),jint,1backup_1remaining)( - JniArgsEnvClass, jobject jBack + JniArgsEnvClass, jlong jpBack ){ - return sqlite3_backup_remaining(PtrGet_sqlite3_backup(jBack)); + return sqlite3_backup_remaining(S3JniLongPtr_sqlite3_backup(jpBack)); } S3JniApi(sqlite3_backup_step(),jint,1backup_1step)( - JniArgsEnvClass, jobject jBack, jint nPage + JniArgsEnvClass, jlong jpBack, jint nPage ){ - return sqlite3_backup_step(PtrGet_sqlite3_backup(jBack), (int)nPage); + return sqlite3_backup_step(S3JniLongPtr_sqlite3_backup(jpBack), (int)nPage); } S3JniApi(sqlite3_bind_blob(),jint,1bind_1blob)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jbyteArray baData, jint nMax + JniArgsEnvClass, jlong jpStmt, jint ndx, jbyteArray baData, jint nMax ){ - jbyte * const pBuf = baData ? s3jni_jbyteArray_bytes(baData) : 0; + jsize nBA = 0; + jbyte * const pBuf = baData ? s3jni_jbyteArray_bytes2(baData, &nBA) : 0; int rc; if( pBuf ){ - rc = sqlite3_bind_blob(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, + if( nMax>nBA ){ + nMax = nBA; + } + rc = sqlite3_bind_blob(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, pBuf, (int)nMax, SQLITE_TRANSIENT); s3jni_jbyteArray_release(baData, pBuf); }else{ rc = baData ? SQLITE_NOMEM - : sqlite3_bind_null( PtrGet_sqlite3_stmt(jpStmt), ndx ); + : sqlite3_bind_null( S3JniLongPtr_sqlite3_stmt(jpStmt), ndx ); } return (jint)rc; } S3JniApi(sqlite3_bind_double(),jint,1bind_1double)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jdouble val + JniArgsEnvClass, jlong jpStmt, jint ndx, jdouble val ){ - return (jint)sqlite3_bind_double(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (double)val); + return (jint)sqlite3_bind_double(S3JniLongPtr_sqlite3_stmt(jpStmt), + (int)ndx, (double)val); } S3JniApi(sqlite3_bind_int(),jint,1bind_1int)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jint val + JniArgsEnvClass, jlong jpStmt, jint ndx, jint val ){ - return (jint)sqlite3_bind_int(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (int)val); + return (jint)sqlite3_bind_int(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, (int)val); } S3JniApi(sqlite3_bind_int64(),jint,1bind_1int64)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jlong val + JniArgsEnvClass, jlong jpStmt, jint ndx, jlong val ){ - return (jint)sqlite3_bind_int64(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (sqlite3_int64)val); + return (jint)sqlite3_bind_int64(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, (sqlite3_int64)val); } /* ** Bind a new global ref to Object `val` using sqlite3_bind_pointer(). */ S3JniApi(sqlite3_bind_java_object(),jint,1bind_1java_1object)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jobject val + JniArgsEnvClass, jlong jpStmt, jint ndx, jobject val ){ - sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); - int rc = 0; + sqlite3_stmt * const pStmt = S3JniLongPtr_sqlite3_stmt(jpStmt); + int rc = SQLITE_MISUSE; if(pStmt){ - jobject const rv = val ? S3JniRefGlobal(val) : 0; + jobject const rv = S3JniRefGlobal(val); if( rv ){ rc = sqlite3_bind_pointer(pStmt, ndx, rv, ResultJavaValuePtrStr, S3Jni_jobject_finalizer); }else if(val){ rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_bind_null(pStmt, ndx); } - }else{ - rc = SQLITE_MISUSE; } return rc; } S3JniApi(sqlite3_bind_null(),jint,1bind_1null)( - JniArgsEnvClass, jobject jpStmt, jint ndx + JniArgsEnvClass, jlong jpStmt, jint ndx ){ - return (jint)sqlite3_bind_null(PtrGet_sqlite3_stmt(jpStmt), (int)ndx); + return (jint)sqlite3_bind_null(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx); +} + +S3JniApi(sqlite3_bind_parameter_count(),jint,1bind_1parameter_1count)( + JniArgsEnvClass, jlong jpStmt +){ + return (jint)sqlite3_bind_parameter_count(S3JniLongPtr_sqlite3_stmt(jpStmt)); } S3JniApi(sqlite3_bind_parameter_index(),jint,1bind_1parameter_1index)( - JniArgsEnvClass, jobject jpStmt, jbyteArray jName + JniArgsEnvClass, jlong jpStmt, jbyteArray jName ){ int rc = 0; jbyte * const pBuf = s3jni_jbyteArray_bytes(jName); if( pBuf ){ - rc = sqlite3_bind_parameter_index(PtrGet_sqlite3_stmt(jpStmt), + rc = sqlite3_bind_parameter_index(S3JniLongPtr_sqlite3_stmt(jpStmt), (const char *)pBuf); s3jni_jbyteArray_release(jName, pBuf); } @@ -2364,73 +2455,108 @@ S3JniApi(sqlite3_bind_parameter_index(),jint,1bind_1parameter_1index)( } S3JniApi(sqlite3_bind_parameter_name(),jstring,1bind_1parameter_1name)( - JniArgsEnvClass, jobject jpStmt, jint ndx + JniArgsEnvClass, jlong jpStmt, jint ndx ){ - jstring rv = 0; const char *z = - sqlite3_bind_parameter_name(PtrGet_sqlite3_stmt(jpStmt), (int)ndx); + sqlite3_bind_parameter_name(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx); + return z ? s3jni_utf8_to_jstring(z, -1) : 0; +} - if( z ){ - rv = s3jni_utf8_to_jstring(z, -1); +/* +** Impl of sqlite3_bind_text/text16(). +*/ +static int s3jni__bind_text(int is16, JNIEnv *env, jlong jpStmt, jint ndx, + jbyteArray baData, jint nMax){ + jsize nBA = 0; + jbyte * const pBuf = + baData ? s3jni_jbyteArray_bytes2(baData, &nBA) : 0; + int rc; + if( pBuf ){ + if( nMax>nBA ){ + nMax = nBA; + } + /* Note that we rely on the Java layer having assured that baData + is NUL-terminated if nMax is negative. In order to avoid UB for + such cases, we do not expose the byte-limit arguments in the + public API. */ + rc = is16 + ? sqlite3_bind_text16(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, + pBuf, (int)nMax, SQLITE_TRANSIENT) + : sqlite3_bind_text(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, + (const char *)pBuf, + (int)nMax, SQLITE_TRANSIENT); + }else{ + rc = baData + ? sqlite3_bind_null(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx) + : SQLITE_NOMEM; } - return rv; + s3jni_jbyteArray_release(baData, pBuf); + return (jint)rc; + } S3JniApi(sqlite3_bind_text(),jint,1bind_1text)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jbyteArray baData, jint nMax + JniArgsEnvClass, jlong jpStmt, jint ndx, jbyteArray baData, jint nMax ){ - jbyte * const pBuf = baData ? s3jni_jbyteArray_bytes(baData) : 0; - int const rc = sqlite3_bind_text(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, - (const char *)pBuf, - (int)nMax, SQLITE_TRANSIENT); - s3jni_jbyteArray_release(baData, pBuf); - return (jint)rc; + return s3jni__bind_text(0, env, jpStmt, ndx, baData, nMax); } S3JniApi(sqlite3_bind_text16(),jint,1bind_1text16)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jbyteArray baData, jint nMax + JniArgsEnvClass, jlong jpStmt, jint ndx, jbyteArray baData, jint nMax ){ - jbyte * const pBuf = baData ? s3jni_jbyteArray_bytes(baData) : 0; - int const rc = sqlite3_bind_text16(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, - pBuf, (int)nMax, SQLITE_TRANSIENT); - s3jni_jbyteArray_release(baData, pBuf); + return s3jni__bind_text(1, env, jpStmt, ndx, baData, nMax); +} + +S3JniApi(sqlite3_bind_value(),jint,1bind_1value)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jlong jpValue +){ + int rc = 0; + sqlite3_stmt * pStmt = S3JniLongPtr_sqlite3_stmt(jpStmt); + if( pStmt ){ + sqlite3_value *v = S3JniLongPtr_sqlite3_value(jpValue); + if( v ){ + rc = sqlite3_bind_value(pStmt, (int)ndx, v); + }else{ + rc = sqlite3_bind_null(pStmt, (int)ndx); + } + }else{ + rc = SQLITE_MISUSE; + } return (jint)rc; } S3JniApi(sqlite3_bind_zeroblob(),jint,1bind_1zeroblob)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jint n + JniArgsEnvClass, jlong jpStmt, jint ndx, jint n ){ - return (jint)sqlite3_bind_zeroblob(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (int)n); + return (jint)sqlite3_bind_zeroblob(S3JniLongPtr_sqlite3_stmt(jpStmt), + (int)ndx, (int)n); } -S3JniApi(sqlite3_bind_zeroblob(),jint,1bind_1zeroblob64)( - JniArgsEnvClass, jobject jpStmt, jint ndx, jlong n +S3JniApi(sqlite3_bind_zeroblob64(),jint,1bind_1zeroblob64)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jlong n ){ - return (jint)sqlite3_bind_zeroblob(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (sqlite3_uint64)n); + return (jint)sqlite3_bind_zeroblob64(S3JniLongPtr_sqlite3_stmt(jpStmt), + (int)ndx, (sqlite3_uint64)n); } S3JniApi(sqlite3_blob_bytes(),jint,1blob_1bytes)( - JniArgsEnvClass, jobject jBlob + JniArgsEnvClass, jlong jpBlob ){ - return sqlite3_blob_bytes(PtrGet_sqlite3_blob(jBlob)); + return sqlite3_blob_bytes(S3JniLongPtr_sqlite3_blob(jpBlob)); } S3JniApi(sqlite3_blob_close(),jint,1blob_1close)( - JniArgsEnvClass, jobject jBlob + JniArgsEnvClass, jlong jpBlob ){ - sqlite3_blob * const b = PtrGet_sqlite3_blob(jBlob); - jint const rc = b ? (jint)sqlite3_blob_close(b) : SQLITE_MISUSE; - if( b ){ - NativePointerHolder_set(S3JniNph(sqlite3_blob), jBlob, 0); - } - return rc; + sqlite3_blob * const b = S3JniLongPtr_sqlite3_blob(jpBlob); + return b ? (jint)sqlite3_blob_close(b) : SQLITE_MISUSE; } S3JniApi(sqlite3_blob_open(),jint,1blob_1open)( - JniArgsEnvClass, jobject jDb, jstring jDbName, jstring jTbl, jstring jCol, + JniArgsEnvClass, jlong jpDb, jstring jDbName, jstring jTbl, jstring jCol, jlong jRowId, jint flags, jobject jOut ){ - sqlite3 * const db = PtrGet_sqlite3(jDb); + sqlite3 * const db = S3JniLongPtr_sqlite3(jpDb); sqlite3_blob * pBlob = 0; char * zDbName = 0, * zTableName = 0, * zColumnName = 0; int rc; @@ -2458,13 +2584,13 @@ S3JniApi(sqlite3_blob_open(),jint,1blob_1open)( } S3JniApi(sqlite3_blob_read(),jint,1blob_1read)( - JniArgsEnvClass, jobject jBlob, jbyteArray jTgt, jint iOffset + JniArgsEnvClass, jlong jpBlob, jbyteArray jTgt, jint iOffset ){ jbyte * const pBa = s3jni_jbyteArray_bytes(jTgt); int rc = jTgt ? (pBa ? SQLITE_MISUSE : SQLITE_NOMEM) : SQLITE_MISUSE; if( pBa ){ jsize const nTgt = (*env)->GetArrayLength(env, jTgt); - rc = sqlite3_blob_read(PtrGet_sqlite3_blob(jBlob), pBa, + rc = sqlite3_blob_read(S3JniLongPtr_sqlite3_blob(jpBlob), pBa, (int)nTgt, (int)iOffset); if( 0==rc ){ s3jni_jbyteArray_commit(jTgt, pBa); @@ -2476,21 +2602,21 @@ S3JniApi(sqlite3_blob_read(),jint,1blob_1read)( } S3JniApi(sqlite3_blob_reopen(),jint,1blob_1reopen)( - JniArgsEnvClass, jobject jBlob, jlong iNewRowId + JniArgsEnvClass, jlong jpBlob, jlong iNewRowId ){ - return (jint)sqlite3_blob_reopen(PtrGet_sqlite3_blob(jBlob), + return (jint)sqlite3_blob_reopen(S3JniLongPtr_sqlite3_blob(jpBlob), (sqlite3_int64)iNewRowId); } S3JniApi(sqlite3_blob_write(),jint,1blob_1write)( - JniArgsEnvClass, jobject jBlob, jbyteArray jBa, jint iOffset + JniArgsEnvClass, jlong jpBlob, jbyteArray jBa, jint iOffset ){ - sqlite3_blob * const b = PtrGet_sqlite3_blob(jBlob); + sqlite3_blob * const b = S3JniLongPtr_sqlite3_blob(jpBlob); jbyte * const pBuf = b ? s3jni_jbyteArray_bytes(jBa) : 0; - const jsize nBa = pBuf ? (*env)->GetArrayLength(env, jBa) : 0; + const jsize nBA = pBuf ? (*env)->GetArrayLength(env, jBa) : 0; int rc = SQLITE_MISUSE; if(b && pBuf){ - rc = sqlite3_blob_write( b, pBuf, (int)nBa, (int)iOffset ); + rc = sqlite3_blob_write( b, pBuf, (int)nBA, (int)iOffset ); } s3jni_jbyteArray_release(jBa, pBuf); return (jint)rc; @@ -2503,7 +2629,7 @@ static int s3jni_busy_handler(void* pState, int n){ S3JniDeclLocal_env; S3JniHook hook; - S3JniHook_localdup(&ps->hooks.busyHandler, &hook ); + S3JniHook_localdup(&ps->hooks.busyHandler, &hook); if( hook.jObj ){ rc = (*env)->CallIntMethod(env, hook.jObj, hook.midCallback, (jint)n); @@ -2518,9 +2644,9 @@ static int s3jni_busy_handler(void* pState, int n){ } S3JniApi(sqlite3_busy_handler(),jint,1busy_1handler)( - JniArgsEnvClass, jobject jDb, jobject jBusy + JniArgsEnvClass, jlong jpDb, jobject jBusy ){ - S3JniDb * const ps = S3JniDb_from_java(jDb); + S3JniDb * const ps = S3JniDb_from_jlong(jpDb); S3JniHook * const pHook = ps ? &ps->hooks.busyHandler : 0; S3JniHook hook = S3JniHook_empty; int rc = 0; @@ -2563,9 +2689,9 @@ S3JniApi(sqlite3_busy_handler(),jint,1busy_1handler)( } S3JniApi(sqlite3_busy_timeout(),jint,1busy_1timeout)( - JniArgsEnvClass, jobject jDb, jint ms + JniArgsEnvClass, jlong jpDb, jint ms ){ - S3JniDb * const ps = S3JniDb_from_java(jDb); + S3JniDb * const ps = S3JniDb_from_jlong(jpDb); int rc = SQLITE_MISUSE; if( ps ){ S3JniDb_mutex_enter; @@ -2582,6 +2708,10 @@ S3JniApi(sqlite3_cancel_auto_extension(),jboolean,1cancel_1auto_1extension)( S3JniAutoExtension * ax; jboolean rc = JNI_FALSE; int i; + + if( !jAutoExt ){ + return rc; + } S3JniAutoExt_mutex_enter; /* This algo corresponds to the one in the core. */ for( i = SJG.autoExt.nExt-1; i >= 0; --i ){ @@ -2602,32 +2732,25 @@ S3JniApi(sqlite3_cancel_auto_extension(),jboolean,1cancel_1auto_1extension)( } /* Wrapper for sqlite3_close(_v2)(). */ -static jint s3jni_close_db(JNIEnv * const env, jobject jDb, int version){ +static jint s3jni_close_db(JNIEnv * const env, jlong jpDb, int version){ int rc = 0; - S3JniDb * const ps = S3JniDb_from_java(jDb); + S3JniDb * const ps = S3JniDb_from_jlong(jpDb); assert(version == 1 || version == 2); if( ps ){ rc = 1==version ? (jint)sqlite3_close(ps->pDb) : (jint)sqlite3_close_v2(ps->pDb); - if( 0==rc ){ - NativePointerHolder_set(S3JniNph(sqlite3), jDb, 0); - } } return (jint)rc; } -S3JniApi(sqlite3_close_v2(),jint,1close_1v2)( - JniArgsEnvClass, jobject pDb -){ - return s3jni_close_db(env, pDb, 2); +S3JniApi(sqlite3_close(),jint,1close)(JniArgsEnvClass, jlong pDb){ + return s3jni_close_db(env, pDb, 1); } -S3JniApi(sqlite3_close(),jint,1close)( - JniArgsEnvClass, jobject pDb -){ - return s3jni_close_db(env, pDb, 1); +S3JniApi(sqlite3_close_v2(),jint,1close_1v2)(JniArgsEnvClass, jlong pDb){ + return s3jni_close_db(env, pDb, 2); } /* @@ -2673,14 +2796,14 @@ static void s3jni_collation_needed_impl16(void *pState, sqlite3 *pDb, } S3JniApi(sqlite3_collation_needed(),jint,1collation_1needed)( - JniArgsEnvClass, jobject jDb, jobject jHook + JniArgsEnvClass, jlong jpDb, jobject jHook ){ S3JniDb * ps; S3JniCollationNeeded * pHook; int rc = 0; S3JniDb_mutex_enter; - ps = S3JniDb_from_java(jDb); + ps = S3JniDb_from_jlong(jpDb); if( !ps ){ S3JniDb_mutex_leave; return SQLITE_MISUSE; @@ -2697,7 +2820,7 @@ S3JniApi(sqlite3_collation_needed(),jint,1collation_1needed)( }else{ jclass const klazz = (*env)->GetObjectClass(env, jHook); jmethodID const xCallback = (*env)->GetMethodID( - env, klazz, "call", "(Lorg/sqlite/jni/sqlite3;ILjava/lang/String;)I" + env, klazz, "call", "(Lorg/sqlite/jni/capi/sqlite3;ILjava/lang/String;)I" ); S3JniUnrefLocal(klazz); S3JniIfThrew { @@ -2751,8 +2874,8 @@ S3JniApi(sqlite3_column_text(),jbyteArray,1column_1text)( JniArgsEnvClass, jobject jpStmt, jint ndx ){ sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt); - const int n = sqlite3_column_bytes(stmt, (int)ndx); - const unsigned char * const p = sqlite3_column_text(stmt, (int)ndx); + const unsigned char * const p = stmt ? sqlite3_column_text(stmt, (int)ndx) : 0; + const int n = p ? sqlite3_column_bytes(stmt, (int)ndx) : 0; return p ? s3jni_new_jbyteArray(p, n) : NULL; } @@ -2762,8 +2885,8 @@ S3JniApi(sqlite3_column_text(),jstring,1column_1text)( JniArgsEnvClass, jobject jpStmt, jint ndx ){ sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt); - const int n = sqlite3_column_bytes(stmt, (int)ndx); - const unsigned char * const p = sqlite3_column_text(stmt, (int)ndx); + const unsigned char * const p = stmt ? sqlite3_column_text(stmt, (int)ndx) : 0; + const int n = p ? sqlite3_column_bytes(stmt, (int)ndx) : 0; return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0; } #endif @@ -2772,8 +2895,8 @@ S3JniApi(sqlite3_column_text16(),jstring,1column_1text16)( JniArgsEnvClass, jobject jpStmt, jint ndx ){ sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt); - const int n = sqlite3_column_bytes16(stmt, (int)ndx); - const void * const p = sqlite3_column_text16(stmt, (int)ndx); + const void * const p = stmt ? sqlite3_column_text16(stmt, (int)ndx) : 0; + const int n = p ? sqlite3_column_bytes16(stmt, (int)ndx) : 0; return s3jni_text16_to_jstring(env, p, n); } @@ -2781,7 +2904,8 @@ S3JniApi(sqlite3_column_value(),jobject,1column_1value)( JniArgsEnvClass, jobject jpStmt, jint ndx ){ sqlite3_value * const sv = - sqlite3_column_value(PtrGet_sqlite3_stmt(jpStmt), (int)ndx); + sqlite3_column_value(PtrGet_sqlite3_stmt(jpStmt), (int)ndx) + /* reminder: returns an SQL NULL if jpStmt==NULL */; return new_java_sqlite3_value(env, sv); } @@ -2823,15 +2947,15 @@ static void s3jni_rollback_hook_impl(void *pP){ ** sqlite3_rollback_hook(). */ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env, - jobject jDb, jobject jHook){ + jlong jpDb, jobject jHook){ S3JniDb * ps; jobject pOld = 0; /* previous hoook */ S3JniHook * pHook; /* ps->hooks.commit|rollback */ S3JniDb_mutex_enter; - ps = S3JniDb_from_java(jDb); + ps = S3JniDb_from_jlong(jpDb); if( !ps ){ - s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0); + s3jni_db_error(ps->pDb, SQLITE_MISUSE, 0); S3JniDb_mutex_leave; return 0; } @@ -2877,9 +3001,9 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env, } S3JniApi(sqlite3_commit_hook(),jobject,1commit_1hook)( - JniArgsEnvClass,jobject jDb, jobject jHook + JniArgsEnvClass, jlong jpDb, jobject jHook ){ - return s3jni_commit_rollback_hook(1, env, jDb, jHook); + return s3jni_commit_rollback_hook(1, env, jpDb, jHook); } S3JniApi(sqlite3_compileoption_get(),jstring,1compileoption_1get)( @@ -2892,33 +3016,34 @@ S3JniApi(sqlite3_compileoption_get(),jstring,1compileoption_1get)( return rv; } -S3JniApi(sqlite3_complete(),int,1complete)( - JniArgsEnvClass, jbyteArray jSql -){ - jbyte * const pBuf = s3jni_jbyteArray_bytes(jSql); - const jsize nBa = pBuf ? (*env)->GetArrayLength(env, jSql) : 0; - int rc; - - assert( (nBa>0 ? 0==pBuf[nBa-1] : (pBuf ? 0==*pBuf : 1)) - && "Byte array is not NUL-terminated." ); - rc = (pBuf && 0==pBuf[(nBa ? nBa-1 : 0)]) - ? sqlite3_complete( (const char *)pBuf ) - : (jSql ? SQLITE_NOMEM : SQLITE_ERROR); - s3jni_jbyteArray_release(jSql, pBuf); - return rc; -} - S3JniApi(sqlite3_compileoption_used(),jboolean,1compileoption_1used)( JniArgsEnvClass, jstring name ){ const char *zUtf8 = s3jni_jstring_to_mutf8(name) - /* We know these to be ASCII, so MUTF-8 is fine. */; + /* We know these to be ASCII, so MUTF-8 is fine (and + hypothetically faster to convert). */; const jboolean rc = 0==sqlite3_compileoption_used(zUtf8) ? JNI_FALSE : JNI_TRUE; s3jni_mutf8_release(name, zUtf8); return rc; } +S3JniApi(sqlite3_complete(),int,1complete)( + JniArgsEnvClass, jbyteArray jSql +){ + jbyte * const pBuf = s3jni_jbyteArray_bytes(jSql); + const jsize nBA = pBuf ? (*env)->GetArrayLength(env, jSql) : 0; + int rc; + + assert( (nBA>0 ? 0==pBuf[nBA-1] : (pBuf ? 0==*pBuf : 1)) + && "Byte array is not NUL-terminated." ); + rc = (pBuf && 0==pBuf[(nBA ? nBA-1 : 0)]) + ? sqlite3_complete( (const char *)pBuf ) + : (jSql ? SQLITE_NOMEM : SQLITE_MISUSE); + s3jni_jbyteArray_release(jSql, pBuf); + return rc; +} + S3JniApi(sqlite3_config() /*for a small subset of options.*/, jint,1config__I)(JniArgsEnvClass, jint n){ switch( n ){ @@ -3045,7 +3170,7 @@ S3JniApi(sqlite3_config() /* for SQLITE_CONFIG_SQLLOG */, }else { jclass const klazz = (*env)->GetObjectClass(env, jLog); jmethodID const midCallback = (*env)->GetMethodID(env, klazz, "call", - "(Lorg/sqlite/jni/sqlite3;" + "(Lorg/sqlite/jni/capi/sqlite3;" "Ljava/lang/String;" "I)V"); S3JniUnrefLocal(klazz); @@ -3123,39 +3248,38 @@ S3JniApi(sqlite3_create_collation() sqlite3_create_collation_v2(), int rc; S3JniDb * ps; + if( !jDb || !name || !encodingTypeIsValid(eTextRep) ){ + return (jint)SQLITE_MISUSE; + } S3JniDb_mutex_enter; ps = S3JniDb_from_java(jDb); - if( !ps ){ - rc = SQLITE_MISUSE; + jclass const klazz = (*env)->GetObjectClass(env, oCollation); + jmethodID const midCallback = + (*env)->GetMethodID(env, klazz, "call", "([B[B)I"); + S3JniUnrefLocal(klazz); + S3JniIfThrew{ + rc = s3jni_db_error(ps->pDb, SQLITE_ERROR, + "Could not get call() method from " + "CollationCallback object."); }else{ - jclass const klazz = (*env)->GetObjectClass(env, oCollation); - jmethodID const midCallback = - (*env)->GetMethodID(env, klazz, "call", "([B[B)I"); - S3JniUnrefLocal(klazz); - S3JniIfThrew{ - rc = s3jni_db_error(ps->pDb, SQLITE_ERROR, - "Could not get call() method from " - "CollationCallback object."); - }else{ - char * const zName = s3jni_jstring_to_utf8(name, 0); - S3JniCollationCallback * const pCC = - zName ? S3JniHook_alloc() : 0; - if( pCC ){ - rc = sqlite3_create_collation_v2(ps->pDb, zName, (int)eTextRep, - pCC, CollationCallback_xCompare, - CollationCallback_xDestroy); - if( 0==rc ){ - pCC->midCallback = midCallback; - pCC->jObj = S3JniRefGlobal(oCollation); - pCC->doXDestroy = 1; - }else{ - CollationCallback_xDestroy(pCC); - } + char * const zName = s3jni_jstring_to_utf8(name, 0); + S3JniCollationCallback * const pCC = + zName ? S3JniHook_alloc() : 0; + if( pCC ){ + rc = sqlite3_create_collation_v2(ps->pDb, zName, (int)eTextRep, + pCC, CollationCallback_xCompare, + CollationCallback_xDestroy); + if( 0==rc ){ + pCC->midCallback = midCallback; + pCC->jObj = S3JniRefGlobal(oCollation); + pCC->doXDestroy = 1; }else{ - rc = SQLITE_NOMEM; + CollationCallback_xDestroy(pCC); } - sqlite3_free(zName); + }else{ + rc = SQLITE_NOMEM; } + sqlite3_free(zName); } S3JniDb_mutex_leave; return (jint)rc; @@ -3171,7 +3295,9 @@ S3JniApi(sqlite3_create_function() sqlite3_create_function_v2() sqlite3 * const pDb = PtrGet_sqlite3(jDb); char * zFuncName = 0; - if( !encodingTypeIsValid(eTextRep) ){ + if( !pDb || !jFuncName ){ + return SQLITE_MISUSE; + }else if( !encodingTypeIsValid(eTextRep) ){ return s3jni_db_error(pDb, SQLITE_FORMAT, "Invalid function encoding option."); } @@ -3215,39 +3341,9 @@ error_cleanup: return (jint)rc; } -S3JniApi(sqlite3_db_filename(),jstring,1db_1filename)( - JniArgsEnvClass, jobject jDb, jstring jDbName -){ - S3JniDb * const ps = S3JniDb_from_java(jDb); - char *zDbName; - jstring jRv = 0; - int nStr = 0; - - if( !ps || !jDbName ){ - return 0; - } - zDbName = s3jni_jstring_to_utf8( jDbName, &nStr); - if( zDbName ){ - char const * zRv = sqlite3_db_filename(ps->pDb, zDbName); - sqlite3_free(zDbName); - if( zRv ){ - jRv = s3jni_utf8_to_jstring( zRv, -1); - } - } - return jRv; -} - -S3JniApi(sqlite3_db_handle(),jobject,1db_1handle)( - JniArgsEnvClass, jobject jpStmt -){ - sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); - sqlite3 * const pDb = pStmt ? sqlite3_db_handle(pStmt) : 0; - S3JniDb * const ps = pDb ? S3JniDb_from_c(pDb) : 0; - return ps ? ps->jDb : 0; -} S3JniApi(sqlite3_db_config() /*for MAINDBNAME*/, - jint,1db_1config__Lorg_sqlite_jni_sqlite3_2ILjava_lang_String_2 + jint,1db_1config__Lorg_sqlite_jni_capi_sqlite3_2ILjava_lang_String_2 )(JniArgsEnvClass, jobject jDb, jint op, jstring jStr){ S3JniDb * const ps = S3JniDb_from_java(jDb); int rc; @@ -3272,6 +3368,7 @@ S3JniApi(sqlite3_db_config() /*for MAINDBNAME*/, } S3JniDb_mutex_leave; break; + case 0: default: rc = SQLITE_MISUSE; } @@ -3283,7 +3380,7 @@ S3JniApi( /* WARNING: openjdk v19 creates a different mangled name for this ** function than openjdk v8 does. We account for that by exporting ** both versions of the name. */ - jint,1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPointer_Int32_2 + jint,1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_Int32_2 )( JniArgsEnvClass, jobject jDb, jint op, jint onOff, jobject jOut ){ @@ -3315,6 +3412,7 @@ S3JniApi( } break; } + case 0: default: rc = SQLITE_MISUSE; } @@ -3327,14 +3425,56 @@ S3JniApi( ** install both names for this function then Java will not be able to ** find the function in both environments. */ -JniDecl(jint,1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPointer_00024Int32_2)( +JniDecl(jint,1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_00024Int32_2)( JniArgsEnvClass, jobject jDb, jint op, jint onOff, jobject jOut ){ - return JniFuncName(1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPointer_Int32_2)( + return JniFuncName(1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_Int32_2)( env, jKlazz, jDb, op, onOff, jOut ); } +S3JniApi(sqlite3_db_filename(),jstring,1db_1filename)( + JniArgsEnvClass, jobject jDb, jstring jDbName +){ + S3JniDb * const ps = S3JniDb_from_java(jDb); + char *zDbName; + jstring jRv = 0; + int nStr = 0; + + if( !ps || !jDbName ){ + return 0; + } + zDbName = s3jni_jstring_to_utf8( jDbName, &nStr); + if( zDbName ){ + char const * zRv = sqlite3_db_filename(ps->pDb, zDbName); + sqlite3_free(zDbName); + if( zRv ){ + jRv = s3jni_utf8_to_jstring( zRv, -1); + } + } + return jRv; +} + +S3JniApi(sqlite3_db_handle(),jobject,1db_1handle)( + JniArgsEnvClass, jobject jpStmt +){ + sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); + sqlite3 * const pDb = pStmt ? sqlite3_db_handle(pStmt) : 0; + S3JniDb * const ps = pDb ? S3JniDb_from_c(pDb) : 0; + return ps ? ps->jDb : 0; +} + +S3JniApi(sqlite3_db_readonly(),jint,1db_1readonly)( + JniArgsEnvClass, jobject jDb, jstring jDbName +){ + int rc = 0; + S3JniDb * const ps = S3JniDb_from_java(jDb); + char *zDbName = jDbName ? s3jni_jstring_to_utf8( jDbName, 0 ) : 0; + rc = sqlite3_db_readonly(ps ? ps->pDb : 0, zDbName); + sqlite3_free(zDbName); + return (jint)rc; +} + S3JniApi(sqlite3_db_release_memory(),int,1db_1release_1memory)( JniArgsEnvClass, jobject jDb ){ @@ -3363,7 +3503,7 @@ S3JniApi(sqlite3_errcode(),jint,1errcode)( return pDb ? sqlite3_errcode(pDb) : SQLITE_MISUSE; } -S3JniApi(sqlite3_errmsg16(),jstring,1errmsg16)( +S3JniApi(sqlite3_errmsg(),jstring,1errmsg)( JniArgsEnvClass, jobject jpDb ){ sqlite3 * const pDb = PtrGet_sqlite3(jpDb); @@ -3383,22 +3523,53 @@ S3JniApi(sqlite3_errstr(),jstring,1errstr)( return rv; } -S3JniApi(sqlite3_expanded_sql(),jstring,1expanded_1sql)( - JniArgsEnvClass, jobject jpStmt -){ +#ifndef SQLITE_ENABLE_NORMALIZE +/* Dummy stub for sqlite3_normalized_sql(). Never called. */ +static const char * sqlite3_normalized_sql(sqlite3_stmt *s){ + S3JniDeclLocal_env; + (*env)->FatalError(env, "dummy sqlite3_normalized_sql() was " + "impossibly called.") /* does not return */; + return 0; +} +#endif + +/* +** Impl for sqlite3_expanded_sql() (if isExpanded is true) and +** sqlite3_normalized_sql(). +*/ +static jstring s3jni_xn_sql(int isExpanded, JNIEnv *env, jobject jpStmt){ jstring rv = 0; sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); + if( pStmt ){ - char * zSql = sqlite3_expanded_sql(pStmt); + char * zSql = isExpanded + ? sqlite3_expanded_sql(pStmt) + : (char*)sqlite3_normalized_sql(pStmt); s3jni_oom_fatal(zSql); if( zSql ){ - rv = s3jni_utf8_to_jstring( zSql, -1); - sqlite3_free(zSql); + rv = s3jni_utf8_to_jstring(zSql, -1); + if( isExpanded ) sqlite3_free(zSql); } } return rv; } +S3JniApi(sqlite3_expanded_sql(),jstring,1expanded_1sql)( + JniArgsEnvClass, jobject jpStmt +){ + return s3jni_xn_sql(1, env, jpStmt); +} + +S3JniApi(sqlite3_normalized_sql(),jstring,1normalized_1sql)( + JniArgsEnvClass, jobject jpStmt +){ +#ifdef SQLITE_ENABLE_NORMALIZE + return s3jni_xn_sql(0, env, jpStmt); +#else + return 0; +#endif +} + S3JniApi(sqlite3_extended_result_codes(),jboolean,1extended_1result_1codes)( JniArgsEnvClass, jobject jpDb, jboolean onoff ){ @@ -3408,15 +3579,11 @@ S3JniApi(sqlite3_extended_result_codes(),jboolean,1extended_1result_1codes)( } S3JniApi(sqlite3_finalize(),jint,1finalize)( - JniArgsEnvClass, jobject jpStmt + JniArgsEnvClass, jlong jpStmt ){ - int rc = 0; - sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); - if( pStmt ){ - rc = sqlite3_finalize(pStmt); - NativePointerHolder_set(S3JniNph(sqlite3_stmt), jpStmt, 0); - } - return rc; + return jpStmt + ? sqlite3_finalize(S3JniLongPtr_sqlite3_stmt(jpStmt)) + : 0; } S3JniApi(sqlite3_get_auxdata(),jobject,1get_1auxdata)( @@ -3496,12 +3663,7 @@ S3JniApi(sqlite3_keyword_name(),jstring,1keyword_1name)( S3JniApi(sqlite3_last_insert_rowid(),jlong,1last_1insert_1rowid)( JniArgsEnvClass, jobject jpDb ){ - jlong rc = 0; - sqlite3 * const pDb = PtrGet_sqlite3(jpDb); - if( pDb ){ - rc = (jlong)sqlite3_last_insert_rowid(pDb); - } - return rc; + return (jlong)sqlite3_last_insert_rowid(PtrGet_sqlite3(jpDb)); } S3JniApi(sqlite3_limit(),jint,1limit)( @@ -3521,6 +3683,7 @@ static int s3jni_open_pre(JNIEnv * const env, S3JniEnv **jc, S3JniDb ** ps){ int rc = 0; jobject jDb = 0; + *jc = S3JniEnv_get(); if( !*jc ){ rc = SQLITE_NOMEM; @@ -3552,7 +3715,7 @@ end: /* ** Post-open() code common to both the sqlite3_open() and ** sqlite3_open_v2() bindings. ps->jDb must be the -** org.sqlite.jni.sqlite3 object which will hold the db's native +** org.sqlite.jni.capi.sqlite3 object which will hold the db's native ** pointer. theRc must be the result code of the open() op. If ** *ppDb is NULL then ps is set aside and its state cleared, ** else ps is associated with *ppDb. If *ppDb is not NULL then @@ -3597,6 +3760,8 @@ S3JniApi(sqlite3_open(),jint,1open)( S3JniDb * ps = 0; S3JniEnv * jc = 0; int rc; + + if( 0==jOut ) return SQLITE_MISUSE; rc = s3jni_open_pre(env, &jc, strName, &zName, &ps); if( 0==rc ){ rc = s3jni_open_post(env, jc, ps, &pOut, jOut, @@ -3609,14 +3774,17 @@ S3JniApi(sqlite3_open(),jint,1open)( S3JniApi(sqlite3_open_v2(),jint,1open_1v2)( JniArgsEnvClass, jstring strName, - jobject jOut, jint flags, jstring strVfs + jobject jOut, jint flags, jstring strVfs ){ sqlite3 * pOut = 0; char *zName = 0; S3JniDb * ps = 0; S3JniEnv * jc = 0; char *zVfs = 0; - int rc = s3jni_open_pre(env, &jc, strName, &zName, &ps); + int rc; + + if( 0==jOut ) return SQLITE_MISUSE; + rc = s3jni_open_pre(env, &jc, strName, &zName, &ps); if( 0==rc ){ if( strVfs ){ zVfs = s3jni_jstring_to_utf8( strVfs, 0); @@ -3637,16 +3805,21 @@ S3JniApi(sqlite3_open_v2(),jint,1open_1v2)( /* Proxy for the sqlite3_prepare[_v2/3]() family. */ jint sqlite3_jni_prepare_v123( int prepVersion, JNIEnv * const env, jclass self, - jobject jDb, jbyteArray baSql, + jlong jpDb, jbyteArray baSql, jint nMax, jint prepFlags, jobject jOutStmt, jobject outTail){ sqlite3_stmt * pStmt = 0; jobject jStmt = 0; const char * zTail = 0; - jbyte * const pBuf = s3jni_jbyteArray_bytes(baSql); + sqlite3 * const pDb = S3JniLongPtr_sqlite3(jpDb); + jbyte * const pBuf = pDb ? s3jni_jbyteArray_bytes(baSql) : 0; int rc = SQLITE_ERROR; + assert(prepVersion==1 || prepVersion==2 || prepVersion==3); - if( !pBuf ){ + if( !pDb || !jOutStmt ){ + rc = SQLITE_MISUSE; + goto end; + }else if( !pBuf ){ rc = baSql ? SQLITE_NOMEM : SQLITE_MISUSE; goto end; } @@ -3656,18 +3829,18 @@ jint sqlite3_jni_prepare_v123( int prepVersion, JNIEnv * const env, jclass self, goto end; } switch( prepVersion ){ - case 1: rc = sqlite3_prepare(PtrGet_sqlite3(jDb), (const char *)pBuf, + case 1: rc = sqlite3_prepare(pDb, (const char *)pBuf, (int)nMax, &pStmt, &zTail); break; - case 2: rc = sqlite3_prepare_v2(PtrGet_sqlite3(jDb), (const char *)pBuf, + case 2: rc = sqlite3_prepare_v2(pDb, (const char *)pBuf, (int)nMax, &pStmt, &zTail); break; - case 3: rc = sqlite3_prepare_v3(PtrGet_sqlite3(jDb), (const char *)pBuf, + case 3: rc = sqlite3_prepare_v3(pDb, (const char *)pBuf, (int)nMax, (unsigned int)prepFlags, &pStmt, &zTail); break; default: - assert(0 && "Invalid prepare() version"); + assert(!"Invalid prepare() version"); } end: s3jni_jbyteArray_release(baSql,pBuf); @@ -3692,29 +3865,31 @@ end: S3JniUnrefLocal(jStmt); jStmt = 0; } - OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_stmt), - jOutStmt, jStmt); + if( jOutStmt ){ + OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_stmt), + jOutStmt, jStmt); + } return (jint)rc; } S3JniApi(sqlite3_prepare(),jint,1prepare)( - JNIEnv * const env, jclass self, jobject jDb, jbyteArray baSql, + JNIEnv * const env, jclass self, jlong jpDb, jbyteArray baSql, jint nMax, jobject jOutStmt, jobject outTail ){ - return sqlite3_jni_prepare_v123(1, env, self, jDb, baSql, nMax, 0, + return sqlite3_jni_prepare_v123(1, env, self, jpDb, baSql, nMax, 0, jOutStmt, outTail); } S3JniApi(sqlite3_prepare_v2(),jint,1prepare_1v2)( - JNIEnv * const env, jclass self, jobject jDb, jbyteArray baSql, + JNIEnv * const env, jclass self, jlong jpDb, jbyteArray baSql, jint nMax, jobject jOutStmt, jobject outTail ){ - return sqlite3_jni_prepare_v123(2, env, self, jDb, baSql, nMax, 0, + return sqlite3_jni_prepare_v123(2, env, self, jpDb, baSql, nMax, 0, jOutStmt, outTail); } S3JniApi(sqlite3_prepare_v3(),jint,1prepare_1v3)( - JNIEnv * const env, jclass self, jobject jDb, jbyteArray baSql, + JNIEnv * const env, jclass self, jlong jpDb, jbyteArray baSql, jint nMax, jint prepFlags, jobject jOutStmt, jobject outTail ){ - return sqlite3_jni_prepare_v123(3, env, self, jDb, baSql, nMax, + return sqlite3_jni_prepare_v123(3, env, self, jpDb, baSql, nMax, prepFlags, jOutStmt, outTail); } @@ -3789,22 +3964,22 @@ static void s3jni_update_hook_impl(void * pState, int opId, const char *zDb, return s3jni_updatepre_hook_impl(pState, NULL, opId, zDb, zTable, nRowid, 0); } -#ifndef SQLITE_ENABLE_PREUPDATE_HOOK +#if !defined(SQLITE_ENABLE_PREUPDATE_HOOK) /* We need no-op impls for preupdate_{count,depth,blobwrite}() */ S3JniApi(sqlite3_preupdate_blobwrite(),int,1preupdate_1blobwrite)( - JniArgsEnvClass, jobject jDb){ return SQLITE_MISUSE; } + JniArgsEnvClass, jlong jDb){ return SQLITE_MISUSE; } S3JniApi(sqlite3_preupdate_count(),int,1preupdate_1count)( - JniArgsEnvClass, jobject jDb){ return SQLITE_MISUSE; } + JniArgsEnvClass, jlong jDb){ return SQLITE_MISUSE; } S3JniApi(sqlite3_preupdate_depth(),int,1preupdate_1depth)( - JniArgsEnvClass, jobject jDb){ return SQLITE_MISUSE; } + JniArgsEnvClass, jlong jDb){ return SQLITE_MISUSE; } #endif /* !SQLITE_ENABLE_PREUPDATE_HOOK */ /* ** JNI wrapper for both sqlite3_update_hook() and ** sqlite3_preupdate_hook() (if isPre is true). */ -static jobject s3jni_updatepre_hook(JNIEnv * env, int isPre, jobject jDb, jobject jHook){ - S3JniDb * const ps = S3JniDb_from_java(jDb); +static jobject s3jni_updatepre_hook(JNIEnv * env, int isPre, jlong jpDb, jobject jHook){ + S3JniDb * const ps = S3JniDb_from_jlong(jpDb); jclass klazz; jobject pOld = 0; jmethodID xCallback; @@ -3843,7 +4018,7 @@ static jobject s3jni_updatepre_hook(JNIEnv * env, int isPre, jobject jDb, jobjec klazz = (*env)->GetObjectClass(env, jHook); xCallback = isPre ? (*env)->GetMethodID(env, klazz, "call", - "(Lorg/sqlite/jni/sqlite3;" + "(Lorg/sqlite/jni/capi/sqlite3;" "I" "Ljava/lang/String;" "Ljava/lang/String;" @@ -3877,20 +4052,20 @@ end: S3JniApi(sqlite3_preupdate_hook(),jobject,1preupdate_1hook)( - JniArgsEnvClass, jobject jDb, jobject jHook + JniArgsEnvClass, jlong jpDb, jobject jHook ){ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - return s3jni_updatepre_hook(env, 1, jDb, jHook); + return s3jni_updatepre_hook(env, 1, jpDb, jHook); #else return NULL; #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ } /* Impl for sqlite3_preupdate_{new,old}(). */ -static int s3jni_preupdate_newold(JNIEnv * const env, int isNew, jobject jDb, +static int s3jni_preupdate_newold(JNIEnv * const env, int isNew, jlong jpDb, jint iCol, jobject jOut){ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - sqlite3 * const pDb = PtrGet_sqlite3(jDb); + sqlite3 * const pDb = S3JniLongPtr_sqlite3(jpDb); int rc = SQLITE_MISUSE; if( pDb ){ sqlite3_value * pOut = 0; @@ -3914,15 +4089,15 @@ static int s3jni_preupdate_newold(JNIEnv * const env, int isNew, jobject jDb, } S3JniApi(sqlite3_preupdate_new(),jint,1preupdate_1new)( - JniArgsEnvClass, jobject jDb, jint iCol, jobject jOut + JniArgsEnvClass, jlong jpDb, jint iCol, jobject jOut ){ - return s3jni_preupdate_newold(env, 1, jDb, iCol, jOut); + return s3jni_preupdate_newold(env, 1, jpDb, iCol, jOut); } S3JniApi(sqlite3_preupdate_old(),jint,1preupdate_1old)( - JniArgsEnvClass, jobject jDb, jint iCol, jobject jOut + JniArgsEnvClass, jlong jpDb, jint iCol, jobject jOut ){ - return s3jni_preupdate_newold(env, 0, jDb, iCol, jOut); + return s3jni_preupdate_newold(env, 0, jpDb, iCol, jOut); } @@ -4017,11 +4192,14 @@ static void result_blob_text(int as64 /* true for text64/blob64() mode */, JNIEnv * const env, sqlite3_context *pCx, jbyteArray jBa, jlong nMax){ int const asBlob = 0==eTextRep; - if( jBa ){ + if( !pCx ){ + /* We should arguably emit a warning here. But where to log it? */ + return; + }else if( jBa ){ jbyte * const pBuf = s3jni_jbyteArray_bytes(jBa); - jsize nBa = (*env)->GetArrayLength(env, jBa); - if( nMax>=0 && nBa>(jsize)nMax ){ - nBa = (jsize)nMax; + jsize nBA = (*env)->GetArrayLength(env, jBa); + if( nMax>=0 && nBA>(jsize)nMax ){ + nBA = (jsize)nMax; /** From the sqlite docs: @@ -4033,7 +4211,7 @@ static void result_blob_text(int as64 /* true for text64/blob64() mode */, Note that the text64() interfaces take an unsigned value for the length, which Java does not support. This binding takes the approach of passing on negative values to the C API, - which will, in turn fail with SQLITE_TOOBIG at some later + which will in turn fail with SQLITE_TOOBIG at some later point (recall that the sqlite3_result_xyz() family do not have result values). */ @@ -4041,15 +4219,15 @@ static void result_blob_text(int as64 /* true for text64/blob64() mode */, if( as64 ){ /* 64-bit... */ static const jsize nLimit64 = SQLITE_MAX_ALLOCATION_SIZE/*only _kinda_ arbitrary*/; - if( nBa > nLimit64 ){ + if( nBA > nLimit64 ){ sqlite3_result_error_toobig(pCx); }else if( asBlob ){ - sqlite3_result_blob64(pCx, pBuf, (sqlite3_uint64)nBa, + sqlite3_result_blob64(pCx, pBuf, (sqlite3_uint64)nBA, SQLITE_TRANSIENT); }else{ /* text64... */ if( encodingTypeIsValid(eTextRep) ){ sqlite3_result_text64(pCx, (const char *)pBuf, - (sqlite3_uint64)nBa, + (sqlite3_uint64)nBA, SQLITE_TRANSIENT, eTextRep); }else{ sqlite3_result_error_code(pCx, SQLITE_FORMAT); @@ -4057,27 +4235,27 @@ static void result_blob_text(int as64 /* true for text64/blob64() mode */, } }else{ /* 32-bit... */ static const jsize nLimit = SQLITE_MAX_ALLOCATION_SIZE; - if( nBa > nLimit ){ + if( nBA > nLimit ){ sqlite3_result_error_toobig(pCx); }else if( asBlob ){ - sqlite3_result_blob(pCx, pBuf, (int)nBa, + sqlite3_result_blob(pCx, pBuf, (int)nBA, SQLITE_TRANSIENT); }else{ switch( eTextRep ){ case SQLITE_UTF8: - sqlite3_result_text(pCx, (const char *)pBuf, (int)nBa, + sqlite3_result_text(pCx, (const char *)pBuf, (int)nBA, SQLITE_TRANSIENT); break; case SQLITE_UTF16: - sqlite3_result_text16(pCx, (const char *)pBuf, (int)nBa, + sqlite3_result_text16(pCx, (const char *)pBuf, (int)nBA, SQLITE_TRANSIENT); break; case SQLITE_UTF16LE: - sqlite3_result_text16le(pCx, (const char *)pBuf, (int)nBa, + sqlite3_result_text16le(pCx, (const char *)pBuf, (int)nBA, SQLITE_TRANSIENT); break; case SQLITE_UTF16BE: - sqlite3_result_text16be(pCx, (const char *)pBuf, (int)nBa, + sqlite3_result_text16be(pCx, (const char *)pBuf, (int)nBA, SQLITE_TRANSIENT); break; } @@ -4167,10 +4345,12 @@ S3JniApi(sqlite3_result_int64(),void,1result_1int64)( S3JniApi(sqlite3_result_java_object(),void,1result_1java_1object)( JniArgsEnvClass, jobject jpCx, jobject v ){ - if( v ){ + sqlite3_context * pCx = PtrGet_sqlite3_context(jpCx); + if( !pCx ) return; + else if( v ){ jobject const rjv = S3JniRefGlobal(v); if( rjv ){ - sqlite3_result_pointer(PtrGet_sqlite3_context(jpCx), rjv, + sqlite3_result_pointer(pCx, rjv, ResultJavaValuePtrStr, S3Jni_jobject_finalizer); }else{ sqlite3_result_error_nomem(PtrGet_sqlite3_context(jpCx)); @@ -4222,9 +4402,9 @@ S3JniApi(sqlite3_result_zeroblob64(),jint,1result_1zeroblob64)( } S3JniApi(sqlite3_rollback_hook(),jobject,1rollback_1hook)( - JniArgsEnvClass, jobject jDb, jobject jHook + JniArgsEnvClass, jlong jpDb, jobject jHook ){ - return s3jni_commit_rollback_hook(0, env, jDb, jHook); + return s3jni_commit_rollback_hook(0, env, jpDb, jHook); } /* Callback for sqlite3_set_authorizer(). */ @@ -4416,7 +4596,6 @@ static int s3jni_strlike_glob(int isLike, JNIEnv *const env, jbyte * const pG = s3jni_jbyteArray_bytes(baG); jbyte * const pT = pG ? s3jni_jbyteArray_bytes(baT) : 0; - s3jni_oom_fatal(pT); /* Note that we're relying on the byte arrays having been NUL-terminated on the Java side. */ rc = isLike @@ -4456,12 +4635,8 @@ S3JniApi(sqlite3_sql(),jstring,1sql)( S3JniApi(sqlite3_step(),jint,1step)( JniArgsEnvClass,jobject jStmt ){ - int rc = SQLITE_MISUSE; sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jStmt); - if( pStmt ){ - rc = sqlite3_step(pStmt); - } - return rc; + return pStmt ? (jint)sqlite3_step(pStmt) : (jint)SQLITE_MISUSE; } S3JniApi(sqlite3_table_column_metadata(),int,1table_1column_1metadata)( @@ -4476,11 +4651,12 @@ S3JniApi(sqlite3_table_column_metadata(),int,1table_1column_1metadata)( int pNotNull = 0, pPrimaryKey = 0, pAutoinc = 0; int rc; - if( !db || !jDbName || !jTableName || !jColumnName ) return SQLITE_MISUSE; + if( !db || !jDbName || !jTableName ) return SQLITE_MISUSE; zDbName = s3jni_jstring_to_utf8(jDbName,0); zTableName = zDbName ? s3jni_jstring_to_utf8(jTableName,0) : 0; - zColumnName = zTableName ? s3jni_jstring_to_utf8(jColumnName,0) : 0; - rc = zColumnName + zColumnName = (zTableName && jColumnName) + ? s3jni_jstring_to_utf8(jColumnName,0) : 0; + rc = zTableName ? sqlite3_table_column_metadata(db, zDbName, zTableName, zColumnName, &pzDataType, &pzCollSeq, &pNotNull, &pPrimaryKey, &pAutoinc) @@ -4630,18 +4806,18 @@ S3JniApi(sqlite3_txn_state(),jint,1txn_1state)( } S3JniApi(sqlite3_update_hook(),jobject,1update_1hook)( - JniArgsEnvClass, jobject jDb, jobject jHook + JniArgsEnvClass, jlong jpDb, jobject jHook ){ - return s3jni_updatepre_hook(env, 0, jDb, jHook); + return s3jni_updatepre_hook(env, 0, jpDb, jHook); } S3JniApi(sqlite3_value_blob(),jbyteArray,1value_1blob)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - sqlite3_value * const sv = PtrGet_sqlite3_value(jpSVal); - int const nLen = sqlite3_value_bytes(sv); - const jbyte * pBytes = sqlite3_value_blob(sv); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + const jbyte * pBytes = sv ? sqlite3_value_blob(sv) : 0; + int const nLen = pBytes ? sqlite3_value_bytes(sv) : 0; s3jni_oom_check( nLen ? !!pBytes : 1 ); return pBytes @@ -4649,74 +4825,102 @@ S3JniApi(sqlite3_value_blob(),jbyteArray,1value_1blob)( : NULL; } +S3JniApi(sqlite3_value_bytes(),int,1value_1bytes)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return sv ? sqlite3_value_bytes(sv) : 0; +} + +S3JniApi(sqlite3_value_bytes16(),int,1value_1bytes16)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return sv ? sqlite3_value_bytes16(sv) : 0; +} + S3JniApi(sqlite3_value_double(),jdouble,1value_1double)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - return (jdouble) sqlite3_value_double(PtrGet_sqlite3_value(jpSVal)); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return (jdouble) (sv ? sqlite3_value_double(sv) : 0.0); } S3JniApi(sqlite3_value_dup(),jobject,1value_1dup)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - sqlite3_value * const sv = sqlite3_value_dup(PtrGet_sqlite3_value(jpSVal)); - return sv ? new_java_sqlite3_value(env, sv) : 0; + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + sqlite3_value * const sd = sv ? sqlite3_value_dup(sv) : 0; + jobject rv = sd ? new_java_sqlite3_value(env, sd) : 0; + if( sd && !rv ) { + /* OOM */ + sqlite3_value_free(sd); + } + return rv; } S3JniApi(sqlite3_value_free(),void,1value_1free)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - sqlite3_value_free(PtrGet_sqlite3_value(jpSVal)); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + if( sv ){ + sqlite3_value_free(sv); + } } S3JniApi(sqlite3_value_int(),jint,1value_1int)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - return (jint) sqlite3_value_int(PtrGet_sqlite3_value(jpSVal)); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return (jint) (sv ? sqlite3_value_int(sv) : 0); } S3JniApi(sqlite3_value_int64(),jlong,1value_1int64)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - return (jlong) sqlite3_value_int64(PtrGet_sqlite3_value(jpSVal)); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return (jlong) (sv ? sqlite3_value_int64(sv) : 0LL); } S3JniApi(sqlite3_value_java_object(),jobject,1value_1java_1object)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - return sqlite3_value_pointer(PtrGet_sqlite3_value(jpSVal), - ResultJavaValuePtrStr); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return sv + ? sqlite3_value_pointer(sv, ResultJavaValuePtrStr) + : 0; } S3JniApi(sqlite3_value_text(),jbyteArray,1value_1text)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - sqlite3_value * const sv = PtrGet_sqlite3_value(jpSVal); - int const n = sqlite3_value_bytes(sv); - const unsigned char * const p = sqlite3_value_text(sv); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + const unsigned char * const p = sv ? sqlite3_value_text(sv) : 0; + int const n = p ? sqlite3_value_bytes(sv) : 0; return p ? s3jni_new_jbyteArray(p, n) : 0; } #if 0 // this impl might prove useful. S3JniApi(sqlite3_value_text(),jstring,1value_1text)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - sqlite3_value * const sv = PtrGet_sqlite3_value(jpSVal); - int const n = sqlite3_value_bytes(sv); - const unsigned char * const p = sqlite3_value_text(sv); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + const unsigned char * const p = sv ? sqlite3_value_text(sv) : 0; + int const n = p ? sqlite3_value_bytes(sv) : 0; return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0; } #endif S3JniApi(sqlite3_value_text16(),jstring,1value_1text16)( - JniArgsEnvClass, jobject jpSVal + JniArgsEnvClass, jlong jpSVal ){ - sqlite3_value * const sv = PtrGet_sqlite3_value(jpSVal); - const int n = sqlite3_value_bytes16(sv); - const void * const p = sqlite3_value_text16(sv); - return s3jni_text16_to_jstring(env, p, n); + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + const int n = sv ? sqlite3_value_bytes16(sv) : 0; + const void * const p = sv ? sqlite3_value_text16(sv) : 0; + return p ? s3jni_text16_to_jstring(env, p, n) : 0; } JniDecl(void,1jni_1internal_1details)(JniArgsEnvClass){ @@ -4862,8 +5066,8 @@ static Fts5JniAux * Fts5JniAux_alloc(JNIEnv * const env, jobject jObj){ s->jmid = (*env)->GetMethodID(env, klazz, "call", "(Lorg/sqlite/jni/fts5/Fts5ExtensionApi;" "Lorg/sqlite/jni/fts5/Fts5Context;" - "Lorg/sqlite/jni/sqlite3_context;" - "[Lorg/sqlite/jni/sqlite3_value;)V"); + "Lorg/sqlite/jni/capi/sqlite3_context;" + "[Lorg/sqlite/jni/capi/sqlite3_value;)V"); S3JniUnrefLocal(klazz); S3JniIfThrew{ S3JniExceptionReport; @@ -5026,6 +5230,7 @@ static void s3jni_fts5_extension_function(Fts5ExtensionApi const *pApi, S3JniIfThrew{ udf_report_exception(env, 1, pCx, pAux->zFuncName, "call"); } + udf_unargs(env, jpCx, argc, jArgv); S3JniUnrefLocal(jpFts); S3JniUnrefLocal(jpCx); S3JniUnrefLocal(jArgv); @@ -5139,9 +5344,11 @@ static void s3jni_phraseIter_NToJ(JNIEnv *const env, jobject jIter){ S3JniGlobalType * const g = &S3JniGlobal; assert(g->fts5.jPhraseIter.fidA); - (*env)->SetLongField(env, jIter, g->fts5.jPhraseIter.fidA, (jlong)pSrc->a); + (*env)->SetLongField(env, jIter, g->fts5.jPhraseIter.fidA, + S3JniCast_P2L(pSrc->a)); S3JniExceptionIsFatal("Cannot set Fts5PhraseIter.a field."); - (*env)->SetLongField(env, jIter, g->fts5.jPhraseIter.fidB, (jlong)pSrc->b); + (*env)->SetLongField(env, jIter, g->fts5.jPhraseIter.fidB, + S3JniCast_P2L(pSrc->b)); S3JniExceptionIsFatal("Cannot set Fts5PhraseIter.b field."); } @@ -5150,11 +5357,13 @@ static void s3jni_phraseIter_JToN(JNIEnv *const env, jobject jIter, Fts5PhraseIter * const pDest){ S3JniGlobalType * const g = &S3JniGlobal; assert(g->fts5.jPhraseIter.fidA); - pDest->a = - (const unsigned char *)(*env)->GetLongField(env, jIter, g->fts5.jPhraseIter.fidA); + pDest->a = S3JniCast_L2P( + (*env)->GetLongField(env, jIter, g->fts5.jPhraseIter.fidA) + ); S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.a field."); - pDest->b = - (const unsigned char *)(*env)->GetLongField(env, jIter, g->fts5.jPhraseIter.fidB); + pDest->b = S3JniCast_L2P( + (*env)->GetLongField(env, jIter, g->fts5.jPhraseIter.fidB) + ); S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.b field."); } @@ -5575,7 +5784,7 @@ static int SQLTester_strnotglob(const char *zGlob, const char *z){ } JNIEXPORT jint JNICALL -Java_org_sqlite_jni_tester_SQLTester_strglob( +Java_org_sqlite_jni_capi_SQLTester_strglob( JniArgsEnvClass, jbyteArray baG, jbyteArray baT ){ int rc = 0; @@ -5602,7 +5811,7 @@ static int SQLTester_auto_extension(sqlite3 *pDb, const char **pzErr, } JNIEXPORT void JNICALL -Java_org_sqlite_jni_tester_SQLTester_installCustomExtensions(JniArgsEnvClass){ +Java_org_sqlite_jni_capi_SQLTester_installCustomExtensions(JniArgsEnvClass){ sqlite3_auto_extension( (void(*)(void))SQLTester_auto_extension ); } @@ -5612,14 +5821,11 @@ Java_org_sqlite_jni_tester_SQLTester_installCustomExtensions(JniArgsEnvClass){ //////////////////////////////////////////////////////////////////////// /* -** Called during static init of the SQLite3Jni class to sync certain -** compile-time constants to Java-space. -** -** This routine is part of the reason why we have to #include -** sqlite3.c instead of sqlite3.h. +** Called during static init of the CApi class to set up global +** state. */ JNIEXPORT void JNICALL -Java_org_sqlite_jni_SQLite3Jni_init(JniArgsEnvClass){ +Java_org_sqlite_jni_capi_CApi_init(JniArgsEnvClass){ jclass klazz; memset(&S3JniGlobal, 0, sizeof(S3JniGlobal)); @@ -5661,7 +5867,7 @@ Java_org_sqlite_jni_SQLite3Jni_init(JniArgsEnvClass){ #ifdef SQLITE_ENABLE_FTS5 klazz = (*env)->FindClass(env, "org/sqlite/jni/fts5/Fts5PhraseIter"); - S3JniExceptionIsFatal("Error getting reference to org.sqlite.jni.Fts5PhraseIter."); + S3JniExceptionIsFatal("Error getting reference to org.sqlite.jni.fts5.Fts5PhraseIter."); SJG.fts5.jPhraseIter.fidA = (*env)->GetFieldID(env, klazz, "a", "J"); S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.a field."); SJG.fts5.jPhraseIter.fidB = (*env)->GetFieldID(env, klazz, "b", "J"); diff --git a/ext/jni/src/c/sqlite3-jni.h b/ext/jni/src/c/sqlite3-jni.h index f9b50bec37..bf6df7ac94 100644 --- a/ext/jni/src/c/sqlite3-jni.h +++ b/ext/jni/src/c/sqlite3-jni.h @@ -1,2094 +1,2151 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class org_sqlite_jni_SQLite3Jni */ +/* Header for class org_sqlite_jni_capi_CApi */ -#ifndef _Included_org_sqlite_jni_SQLite3Jni -#define _Included_org_sqlite_jni_SQLite3Jni +#ifndef _Included_org_sqlite_jni_capi_CApi +#define _Included_org_sqlite_jni_capi_CApi #ifdef __cplusplus extern "C" { #endif -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ACCESS_EXISTS -#define org_sqlite_jni_SQLite3Jni_SQLITE_ACCESS_EXISTS 0L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ACCESS_READWRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_ACCESS_READWRITE 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ACCESS_READ -#define org_sqlite_jni_SQLite3Jni_SQLITE_ACCESS_READ 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DENY -#define org_sqlite_jni_SQLite3Jni_SQLITE_DENY 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IGNORE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IGNORE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_INDEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_INDEX 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TABLE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TEMP_INDEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TEMP_INDEX 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TEMP_TABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TEMP_TABLE 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TEMP_TRIGGER -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TEMP_TRIGGER 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TEMP_VIEW -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TEMP_VIEW 6L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TRIGGER -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_TRIGGER 7L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_VIEW -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_VIEW 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DELETE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DELETE 9L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_INDEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_INDEX 10L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TABLE 11L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TEMP_INDEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TEMP_INDEX 12L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TEMP_TABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TEMP_TABLE 13L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TEMP_TRIGGER -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TEMP_TRIGGER 14L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TEMP_VIEW -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TEMP_VIEW 15L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TRIGGER -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_TRIGGER 16L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_VIEW -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_VIEW 17L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INSERT -#define org_sqlite_jni_SQLite3Jni_SQLITE_INSERT 18L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_PRAGMA -#define org_sqlite_jni_SQLite3Jni_SQLITE_PRAGMA 19L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_READ -#define org_sqlite_jni_SQLite3Jni_SQLITE_READ 20L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SELECT -#define org_sqlite_jni_SQLite3Jni_SQLITE_SELECT 21L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TRANSACTION -#define org_sqlite_jni_SQLite3Jni_SQLITE_TRANSACTION 22L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_UPDATE -#define org_sqlite_jni_SQLite3Jni_SQLITE_UPDATE 23L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ATTACH -#define org_sqlite_jni_SQLite3Jni_SQLITE_ATTACH 24L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DETACH -#define org_sqlite_jni_SQLite3Jni_SQLITE_DETACH 25L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ALTER_TABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_ALTER_TABLE 26L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_REINDEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_REINDEX 27L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ANALYZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_ANALYZE 28L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_VTABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CREATE_VTABLE 29L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DROP_VTABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DROP_VTABLE 30L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FUNCTION -#define org_sqlite_jni_SQLite3Jni_SQLITE_FUNCTION 31L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SAVEPOINT -#define org_sqlite_jni_SQLite3Jni_SQLITE_SAVEPOINT 32L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_RECURSIVE -#define org_sqlite_jni_SQLite3Jni_SQLITE_RECURSIVE 33L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STATIC -#define org_sqlite_jni_SQLite3Jni_SQLITE_STATIC 0LL -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TRANSIENT -#define org_sqlite_jni_SQLite3Jni_SQLITE_TRANSIENT -1LL -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESETSTART_INVERT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESETSTART_INVERT 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESETAPPLY_NOSAVEPOINT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESETAPPLY_NOSAVEPOINT 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESETAPPLY_INVERT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESETAPPLY_INVERT 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESETAPPLY_IGNORENOOP -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESETAPPLY_IGNORENOOP 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_DATA -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_DATA 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_NOTFOUND -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_NOTFOUND 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_CONFLICT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_CONFLICT 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_CONSTRAINT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_CONSTRAINT 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_FOREIGN_KEY -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_FOREIGN_KEY 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_OMIT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_OMIT 0L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_REPLACE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_REPLACE 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_ABORT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CHANGESET_ABORT 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SINGLETHREAD -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SINGLETHREAD 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MULTITHREAD -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MULTITHREAD 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SERIALIZED -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SERIALIZED 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MALLOC -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MALLOC 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_GETMALLOC -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_GETMALLOC 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SCRATCH -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SCRATCH 6L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PAGECACHE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PAGECACHE 7L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_HEAP -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_HEAP 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MEMSTATUS -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MEMSTATUS 9L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MUTEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MUTEX 10L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_GETMUTEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_GETMUTEX 11L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_LOOKASIDE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_LOOKASIDE 13L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PCACHE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PCACHE 14L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_GETPCACHE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_GETPCACHE 15L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_LOG -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_LOG 16L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_URI -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_URI 17L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PCACHE2 -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PCACHE2 18L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_GETPCACHE2 -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_GETPCACHE2 19L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_COVERING_INDEX_SCAN -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_COVERING_INDEX_SCAN 20L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SQLLOG -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SQLLOG 21L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MMAP_SIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MMAP_SIZE 22L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_WIN32_HEAPSIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_WIN32_HEAPSIZE 23L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PCACHE_HDRSZ -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PCACHE_HDRSZ 24L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PMASZ -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_PMASZ 25L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_STMTJRNL_SPILL -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_STMTJRNL_SPILL 26L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SMALL_MALLOC -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SMALL_MALLOC 27L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SORTERREF_SIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_SORTERREF_SIZE 28L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MEMDB_MAXSIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONFIG_MEMDB_MAXSIZE 29L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INTEGER -#define org_sqlite_jni_SQLite3Jni_SQLITE_INTEGER 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FLOAT -#define org_sqlite_jni_SQLite3Jni_SQLITE_FLOAT 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TEXT -#define org_sqlite_jni_SQLite3Jni_SQLITE_TEXT 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_BLOB -#define org_sqlite_jni_SQLite3Jni_SQLITE_BLOB 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_NULL -#define org_sqlite_jni_SQLite3Jni_SQLITE_NULL 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_MAINDBNAME -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_MAINDBNAME 1000L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_LOOKASIDE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_LOOKASIDE 1001L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_FKEY -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_FKEY 1002L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_TRIGGER -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_TRIGGER 1003L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_QPSG -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_QPSG 1007L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_TRIGGER_EQP -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_TRIGGER_EQP 1008L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_RESET_DATABASE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_RESET_DATABASE 1009L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_DEFENSIVE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_DEFENSIVE 1010L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_WRITABLE_SCHEMA -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_LEGACY_ALTER_TABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_DQS_DML -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_DQS_DML 1013L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_DQS_DDL -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_DQS_DDL 1014L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_VIEW -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_ENABLE_VIEW 1015L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_LEGACY_FILE_FORMAT -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_TRUSTED_SCHEMA -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_STMT_SCANSTATUS -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_STMT_SCANSTATUS 1018L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_REVERSE_SCANORDER -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_REVERSE_SCANORDER 1019L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_MAX -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBCONFIG_MAX 1019L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_LOOKASIDE_USED -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_LOOKASIDE_USED 0L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_USED -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_USED 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_SCHEMA_USED -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_SCHEMA_USED 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_STMT_USED -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_STMT_USED 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_LOOKASIDE_HIT -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_LOOKASIDE_HIT 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_HIT -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_HIT 7L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_MISS -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_MISS 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_WRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_WRITE 9L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_DEFERRED_FKS -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_DEFERRED_FKS 10L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_USED_SHARED -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_USED_SHARED 11L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_SPILL -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_CACHE_SPILL 12L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_MAX -#define org_sqlite_jni_SQLite3Jni_SQLITE_DBSTATUS_MAX 12L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_UTF8 -#define org_sqlite_jni_SQLite3Jni_SQLITE_UTF8 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_UTF16LE -#define org_sqlite_jni_SQLite3Jni_SQLITE_UTF16LE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_UTF16BE -#define org_sqlite_jni_SQLite3Jni_SQLITE_UTF16BE 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_UTF16 -#define org_sqlite_jni_SQLite3Jni_SQLITE_UTF16 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_UTF16_ALIGNED -#define org_sqlite_jni_SQLite3Jni_SQLITE_UTF16_ALIGNED 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_LOCKSTATE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_LOCKSTATE 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_GET_LOCKPROXYFILE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_GET_LOCKPROXYFILE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SET_LOCKPROXYFILE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SET_LOCKPROXYFILE 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_LAST_ERRNO -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_LAST_ERRNO 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SIZE_HINT -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SIZE_HINT 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_CHUNK_SIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_CHUNK_SIZE 6L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_FILE_POINTER -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_FILE_POINTER 7L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SYNC_OMITTED -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SYNC_OMITTED 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_WIN32_AV_RETRY -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_WIN32_AV_RETRY 9L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_PERSIST_WAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_PERSIST_WAL 10L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_OVERWRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_OVERWRITE 11L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_VFSNAME -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_VFSNAME 12L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_POWERSAFE_OVERWRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_POWERSAFE_OVERWRITE 13L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_PRAGMA -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_PRAGMA 14L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_BUSYHANDLER -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_BUSYHANDLER 15L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_TEMPFILENAME -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_TEMPFILENAME 16L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_MMAP_SIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_MMAP_SIZE 18L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_TRACE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_TRACE 19L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_HAS_MOVED -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_HAS_MOVED 20L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SYNC -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SYNC 21L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_COMMIT_PHASETWO -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_COMMIT_PHASETWO 22L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_WIN32_SET_HANDLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_WIN32_SET_HANDLE 23L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_WAL_BLOCK -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_WAL_BLOCK 24L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_ZIPVFS -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_ZIPVFS 25L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_RBU -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_RBU 26L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_VFS_POINTER -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_VFS_POINTER 27L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_JOURNAL_POINTER -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_JOURNAL_POINTER 28L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_WIN32_GET_HANDLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_WIN32_GET_HANDLE 29L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_PDB -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_PDB 30L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_BEGIN_ATOMIC_WRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_COMMIT_ATOMIC_WRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_LOCK_TIMEOUT -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_LOCK_TIMEOUT 34L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_DATA_VERSION -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_DATA_VERSION 35L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SIZE_LIMIT -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_SIZE_LIMIT 36L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_CKPT_DONE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_CKPT_DONE 37L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_RESERVE_BYTES -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_RESERVE_BYTES 38L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_CKPT_START -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_CKPT_START 39L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_EXTERNAL_READER -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_EXTERNAL_READER 40L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_CKSM_FILE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_CKSM_FILE 41L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_RESET_CACHE -#define org_sqlite_jni_SQLite3Jni_SQLITE_FCNTL_RESET_CACHE 42L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_NONE -#define org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_NONE 0L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_SHARED -#define org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_SHARED 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_RESERVED -#define org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_RESERVED 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_PENDING -#define org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_PENDING 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_EXCLUSIVE -#define org_sqlite_jni_SQLite3Jni_SQLITE_LOCK_EXCLUSIVE 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC512 -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC512 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC1K -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC1K 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC2K -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC2K 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC4K -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC4K 16L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC8K -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC8K 32L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC16K -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC16K 64L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC32K -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC32K 128L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC64K -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_ATOMIC64K 256L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_SAFE_APPEND -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_SAFE_APPEND 512L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_SEQUENTIAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_SEQUENTIAL 1024L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 2048L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_POWERSAFE_OVERWRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_POWERSAFE_OVERWRITE 4096L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_IMMUTABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_IMMUTABLE 8192L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_BATCH_ATOMIC -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_BATCH_ATOMIC 16384L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_LENGTH -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_LENGTH 0L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_SQL_LENGTH -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_SQL_LENGTH 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_COLUMN -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_COLUMN 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_EXPR_DEPTH -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_EXPR_DEPTH 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_COMPOUND_SELECT -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_COMPOUND_SELECT 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_VDBE_OP -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_VDBE_OP 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_FUNCTION_ARG -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_FUNCTION_ARG 6L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_ATTACHED -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_ATTACHED 7L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_LIKE_PATTERN_LENGTH -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_VARIABLE_NUMBER -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_VARIABLE_NUMBER 9L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_TRIGGER_DEPTH -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_TRIGGER_DEPTH 10L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_WORKER_THREADS -#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_WORKER_THREADS 11L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READONLY -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READONLY 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READWRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READWRITE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_CREATE -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_CREATE 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_URI -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_URI 64L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_MEMORY -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_MEMORY 128L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_NOMUTEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_NOMUTEX 32768L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_FULLMUTEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_FULLMUTEX 65536L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_SHAREDCACHE -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_SHAREDCACHE 131072L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_PRIVATECACHE -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_PRIVATECACHE 262144L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_EXRESCODE -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_EXRESCODE 33554432L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_NOFOLLOW -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_NOFOLLOW 16777216L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_MAIN_DB -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_MAIN_DB 256L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_MAIN_JOURNAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_MAIN_JOURNAL 2048L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_TEMP_DB -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_TEMP_DB 512L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_TEMP_JOURNAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_TEMP_JOURNAL 4096L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_TRANSIENT_DB -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_TRANSIENT_DB 1024L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_SUBJOURNAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_SUBJOURNAL 8192L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_SUPER_JOURNAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_SUPER_JOURNAL 16384L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_WAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_WAL 524288L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_DELETEONCLOSE -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_DELETEONCLOSE 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_EXCLUSIVE -#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_EXCLUSIVE 16L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_PREPARE_PERSISTENT -#define org_sqlite_jni_SQLite3Jni_SQLITE_PREPARE_PERSISTENT 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_PREPARE_NORMALIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_PREPARE_NORMALIZE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_PREPARE_NO_VTAB -#define org_sqlite_jni_SQLite3Jni_SQLITE_PREPARE_NO_VTAB 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OK -#define org_sqlite_jni_SQLite3Jni_SQLITE_OK 0L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ERROR -#define org_sqlite_jni_SQLite3Jni_SQLITE_ERROR 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INTERNAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_INTERNAL 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_PERM -#define org_sqlite_jni_SQLite3Jni_SQLITE_PERM 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ABORT -#define org_sqlite_jni_SQLite3Jni_SQLITE_ABORT 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_BUSY -#define org_sqlite_jni_SQLite3Jni_SQLITE_BUSY 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LOCKED -#define org_sqlite_jni_SQLite3Jni_SQLITE_LOCKED 6L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_NOMEM -#define org_sqlite_jni_SQLite3Jni_SQLITE_NOMEM 7L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_READONLY -#define org_sqlite_jni_SQLite3Jni_SQLITE_READONLY 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INTERRUPT -#define org_sqlite_jni_SQLite3Jni_SQLITE_INTERRUPT 9L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR 10L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CORRUPT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CORRUPT 11L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_NOTFOUND -#define org_sqlite_jni_SQLite3Jni_SQLITE_NOTFOUND 12L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FULL -#define org_sqlite_jni_SQLite3Jni_SQLITE_FULL 13L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN -#define org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN 14L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_PROTOCOL -#define org_sqlite_jni_SQLite3Jni_SQLITE_PROTOCOL 15L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_EMPTY -#define org_sqlite_jni_SQLite3Jni_SQLITE_EMPTY 16L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SCHEMA -#define org_sqlite_jni_SQLite3Jni_SQLITE_SCHEMA 17L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TOOBIG -#define org_sqlite_jni_SQLite3Jni_SQLITE_TOOBIG 18L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT 19L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_MISMATCH -#define org_sqlite_jni_SQLite3Jni_SQLITE_MISMATCH 20L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_MISUSE -#define org_sqlite_jni_SQLite3Jni_SQLITE_MISUSE 21L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_NOLFS -#define org_sqlite_jni_SQLite3Jni_SQLITE_NOLFS 22L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_AUTH -#define org_sqlite_jni_SQLite3Jni_SQLITE_AUTH 23L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FORMAT -#define org_sqlite_jni_SQLite3Jni_SQLITE_FORMAT 24L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_RANGE -#define org_sqlite_jni_SQLite3Jni_SQLITE_RANGE 25L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_NOTADB -#define org_sqlite_jni_SQLite3Jni_SQLITE_NOTADB 26L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_NOTICE -#define org_sqlite_jni_SQLite3Jni_SQLITE_NOTICE 27L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_WARNING -#define org_sqlite_jni_SQLite3Jni_SQLITE_WARNING 28L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ROW -#define org_sqlite_jni_SQLite3Jni_SQLITE_ROW 100L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DONE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DONE 101L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ERROR_MISSING_COLLSEQ -#define org_sqlite_jni_SQLite3Jni_SQLITE_ERROR_MISSING_COLLSEQ 257L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ERROR_RETRY -#define org_sqlite_jni_SQLite3Jni_SQLITE_ERROR_RETRY 513L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ERROR_SNAPSHOT -#define org_sqlite_jni_SQLite3Jni_SQLITE_ERROR_SNAPSHOT 769L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_READ -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_READ 266L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHORT_READ -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHORT_READ 522L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_WRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_WRITE 778L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_FSYNC -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_FSYNC 1034L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DIR_FSYNC -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DIR_FSYNC 1290L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_TRUNCATE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_TRUNCATE 1546L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_FSTAT -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_FSTAT 1802L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_UNLOCK -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_UNLOCK 2058L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_RDLOCK -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_RDLOCK 2314L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DELETE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DELETE 2570L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_BLOCKED -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_BLOCKED 2826L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_NOMEM -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_NOMEM 3082L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_ACCESS -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_ACCESS 3338L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_CHECKRESERVEDLOCK -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_CHECKRESERVEDLOCK 3594L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_LOCK -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_LOCK 3850L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_CLOSE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_CLOSE 4106L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DIR_CLOSE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DIR_CLOSE 4362L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHMOPEN -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHMOPEN 4618L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHMSIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHMSIZE 4874L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHMLOCK -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHMLOCK 5130L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHMMAP -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SHMMAP 5386L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SEEK -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_SEEK 5642L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DELETE_NOENT -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DELETE_NOENT 5898L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_MMAP -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_MMAP 6154L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_GETTEMPPATH -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_GETTEMPPATH 6410L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_CONVPATH -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_CONVPATH 6666L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_VNODE -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_VNODE 6922L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_AUTH -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_AUTH 7178L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_BEGIN_ATOMIC -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_BEGIN_ATOMIC 7434L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_COMMIT_ATOMIC -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_COMMIT_ATOMIC 7690L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_ROLLBACK_ATOMIC -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_ROLLBACK_ATOMIC 7946L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DATA -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_DATA 8202L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_CORRUPTFS -#define org_sqlite_jni_SQLite3Jni_SQLITE_IOERR_CORRUPTFS 8458L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LOCKED_SHAREDCACHE -#define org_sqlite_jni_SQLite3Jni_SQLITE_LOCKED_SHAREDCACHE 262L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_LOCKED_VTAB -#define org_sqlite_jni_SQLite3Jni_SQLITE_LOCKED_VTAB 518L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_BUSY_RECOVERY -#define org_sqlite_jni_SQLite3Jni_SQLITE_BUSY_RECOVERY 261L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_BUSY_SNAPSHOT -#define org_sqlite_jni_SQLite3Jni_SQLITE_BUSY_SNAPSHOT 517L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_BUSY_TIMEOUT -#define org_sqlite_jni_SQLite3Jni_SQLITE_BUSY_TIMEOUT 773L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_NOTEMPDIR -#define org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_NOTEMPDIR 270L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_ISDIR -#define org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_ISDIR 526L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_FULLPATH -#define org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_FULLPATH 782L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_CONVPATH -#define org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_CONVPATH 1038L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_SYMLINK -#define org_sqlite_jni_SQLite3Jni_SQLITE_CANTOPEN_SYMLINK 1550L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CORRUPT_VTAB -#define org_sqlite_jni_SQLite3Jni_SQLITE_CORRUPT_VTAB 267L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CORRUPT_SEQUENCE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CORRUPT_SEQUENCE 523L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CORRUPT_INDEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_CORRUPT_INDEX 779L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_RECOVERY -#define org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_RECOVERY 264L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_CANTLOCK -#define org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_CANTLOCK 520L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_ROLLBACK -#define org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_ROLLBACK 776L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_DBMOVED -#define org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_DBMOVED 1032L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_CANTINIT -#define org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_CANTINIT 1288L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_DIRECTORY -#define org_sqlite_jni_SQLite3Jni_SQLITE_READONLY_DIRECTORY 1544L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ABORT_ROLLBACK -#define org_sqlite_jni_SQLite3Jni_SQLITE_ABORT_ROLLBACK 516L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_CHECK -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_CHECK 275L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_COMMITHOOK -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_COMMITHOOK 531L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_FOREIGNKEY -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_FOREIGNKEY 787L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_FUNCTION -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_FUNCTION 1043L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_NOTNULL -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_NOTNULL 1299L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_PRIMARYKEY -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_PRIMARYKEY 1555L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_TRIGGER -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_TRIGGER 1811L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_UNIQUE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_UNIQUE 2067L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_VTAB -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_VTAB 2323L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_ROWID -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_ROWID 2579L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_PINNED -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_PINNED 2835L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_DATATYPE -#define org_sqlite_jni_SQLite3Jni_SQLITE_CONSTRAINT_DATATYPE 3091L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_NOTICE_RECOVER_WAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_NOTICE_RECOVER_WAL 283L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_NOTICE_RECOVER_ROLLBACK -#define org_sqlite_jni_SQLite3Jni_SQLITE_NOTICE_RECOVER_ROLLBACK 539L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_WARNING_AUTOINDEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_WARNING_AUTOINDEX 284L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_AUTH_USER -#define org_sqlite_jni_SQLite3Jni_SQLITE_AUTH_USER 279L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_OK_LOAD_PERMANENTLY -#define org_sqlite_jni_SQLite3Jni_SQLITE_OK_LOAD_PERMANENTLY 256L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SERIALIZE_NOCOPY -#define org_sqlite_jni_SQLite3Jni_SQLITE_SERIALIZE_NOCOPY 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DESERIALIZE_FREEONCLOSE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DESERIALIZE_FREEONCLOSE 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DESERIALIZE_READONLY -#define org_sqlite_jni_SQLite3Jni_SQLITE_DESERIALIZE_READONLY 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DESERIALIZE_RESIZEABLE -#define org_sqlite_jni_SQLite3Jni_SQLITE_DESERIALIZE_RESIZEABLE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SESSION_CONFIG_STRMSIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_SESSION_CONFIG_STRMSIZE 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SESSION_OBJCONFIG_SIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_SESSION_OBJCONFIG_SIZE 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_MEMORY_USED -#define org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_MEMORY_USED 0L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_PAGECACHE_USED -#define org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_PAGECACHE_USED 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_PAGECACHE_OVERFLOW -#define org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_PAGECACHE_OVERFLOW 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_MALLOC_SIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_MALLOC_SIZE 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_PARSER_STACK -#define org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_PARSER_STACK 6L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_PAGECACHE_SIZE -#define org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_PAGECACHE_SIZE 7L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_MALLOC_COUNT -#define org_sqlite_jni_SQLite3Jni_SQLITE_STATUS_MALLOC_COUNT 9L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_FULLSCAN_STEP -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_FULLSCAN_STEP 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_SORT -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_SORT 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_AUTOINDEX -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_AUTOINDEX 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_VM_STEP -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_VM_STEP 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_REPREPARE -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_REPREPARE 5L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_RUN -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_RUN 6L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_FILTER_MISS -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_FILTER_MISS 7L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_FILTER_HIT -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_FILTER_HIT 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_MEMUSED -#define org_sqlite_jni_SQLite3Jni_SQLITE_STMTSTATUS_MEMUSED 99L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SYNC_NORMAL -#define org_sqlite_jni_SQLite3Jni_SQLITE_SYNC_NORMAL 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SYNC_FULL -#define org_sqlite_jni_SQLite3Jni_SQLITE_SYNC_FULL 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_SYNC_DATAONLY -#define org_sqlite_jni_SQLite3Jni_SQLITE_SYNC_DATAONLY 16L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TRACE_STMT -#define org_sqlite_jni_SQLite3Jni_SQLITE_TRACE_STMT 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TRACE_PROFILE -#define org_sqlite_jni_SQLite3Jni_SQLITE_TRACE_PROFILE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TRACE_ROW -#define org_sqlite_jni_SQLite3Jni_SQLITE_TRACE_ROW 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TRACE_CLOSE -#define org_sqlite_jni_SQLite3Jni_SQLITE_TRACE_CLOSE 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TXN_NONE -#define org_sqlite_jni_SQLite3Jni_SQLITE_TXN_NONE 0L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TXN_READ -#define org_sqlite_jni_SQLite3Jni_SQLITE_TXN_READ 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_TXN_WRITE -#define org_sqlite_jni_SQLite3Jni_SQLITE_TXN_WRITE 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DETERMINISTIC -#define org_sqlite_jni_SQLite3Jni_SQLITE_DETERMINISTIC 2048L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_DIRECTONLY -#define org_sqlite_jni_SQLite3Jni_SQLITE_DIRECTONLY 524288L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INNOCUOUS -#define org_sqlite_jni_SQLite3Jni_SQLITE_INNOCUOUS 2097152L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_SCAN_UNIQUE -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_SCAN_UNIQUE 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_EQ -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_EQ 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_GT -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_GT 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_LE -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_LE 8L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_LT -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_LT 16L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_GE -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_GE 32L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_MATCH -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_MATCH 64L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_LIKE -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_LIKE 65L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_GLOB -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_GLOB 66L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_REGEXP -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_REGEXP 67L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_NE -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_NE 68L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_ISNOT -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_ISNOT 69L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_ISNOTNULL -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_ISNULL -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_ISNULL 71L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_IS -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_IS 72L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_LIMIT -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_LIMIT 73L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_OFFSET -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_OFFSET 74L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_FUNCTION -#define org_sqlite_jni_SQLite3Jni_SQLITE_INDEX_CONSTRAINT_FUNCTION 150L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_VTAB_CONSTRAINT_SUPPORT -#define org_sqlite_jni_SQLite3Jni_SQLITE_VTAB_CONSTRAINT_SUPPORT 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_VTAB_INNOCUOUS -#define org_sqlite_jni_SQLite3Jni_SQLITE_VTAB_INNOCUOUS 2L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_VTAB_DIRECTONLY -#define org_sqlite_jni_SQLite3Jni_SQLITE_VTAB_DIRECTONLY 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_VTAB_USES_ALL_SCHEMAS -#define org_sqlite_jni_SQLite3Jni_SQLITE_VTAB_USES_ALL_SCHEMAS 4L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_ROLLBACK -#define org_sqlite_jni_SQLite3Jni_SQLITE_ROLLBACK 1L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_FAIL -#define org_sqlite_jni_SQLite3Jni_SQLITE_FAIL 3L -#undef org_sqlite_jni_SQLite3Jni_SQLITE_REPLACE -#define org_sqlite_jni_SQLite3Jni_SQLITE_REPLACE 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_ACCESS_EXISTS +#define org_sqlite_jni_capi_CApi_SQLITE_ACCESS_EXISTS 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_ACCESS_READWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_ACCESS_READWRITE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_ACCESS_READ +#define org_sqlite_jni_capi_CApi_SQLITE_ACCESS_READ 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_DENY +#define org_sqlite_jni_capi_CApi_SQLITE_DENY 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_IGNORE +#define org_sqlite_jni_capi_CApi_SQLITE_IGNORE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_INDEX 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TABLE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_INDEX 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_TABLE 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_TRIGGER 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_VIEW 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TRIGGER 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_VIEW 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_DELETE +#define org_sqlite_jni_capi_CApi_SQLITE_DELETE 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_INDEX 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TABLE 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_INDEX 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_TABLE 13L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_TRIGGER 14L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_VIEW 15L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TRIGGER 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_VIEW 17L +#undef org_sqlite_jni_capi_CApi_SQLITE_INSERT +#define org_sqlite_jni_capi_CApi_SQLITE_INSERT 18L +#undef org_sqlite_jni_capi_CApi_SQLITE_PRAGMA +#define org_sqlite_jni_capi_CApi_SQLITE_PRAGMA 19L +#undef org_sqlite_jni_capi_CApi_SQLITE_READ +#define org_sqlite_jni_capi_CApi_SQLITE_READ 20L +#undef org_sqlite_jni_capi_CApi_SQLITE_SELECT +#define org_sqlite_jni_capi_CApi_SQLITE_SELECT 21L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRANSACTION +#define org_sqlite_jni_capi_CApi_SQLITE_TRANSACTION 22L +#undef org_sqlite_jni_capi_CApi_SQLITE_UPDATE +#define org_sqlite_jni_capi_CApi_SQLITE_UPDATE 23L +#undef org_sqlite_jni_capi_CApi_SQLITE_ATTACH +#define org_sqlite_jni_capi_CApi_SQLITE_ATTACH 24L +#undef org_sqlite_jni_capi_CApi_SQLITE_DETACH +#define org_sqlite_jni_capi_CApi_SQLITE_DETACH 25L +#undef org_sqlite_jni_capi_CApi_SQLITE_ALTER_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_ALTER_TABLE 26L +#undef org_sqlite_jni_capi_CApi_SQLITE_REINDEX +#define org_sqlite_jni_capi_CApi_SQLITE_REINDEX 27L +#undef org_sqlite_jni_capi_CApi_SQLITE_ANALYZE +#define org_sqlite_jni_capi_CApi_SQLITE_ANALYZE 28L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_VTABLE +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_VTABLE 29L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_VTABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_VTABLE 30L +#undef org_sqlite_jni_capi_CApi_SQLITE_FUNCTION +#define org_sqlite_jni_capi_CApi_SQLITE_FUNCTION 31L +#undef org_sqlite_jni_capi_CApi_SQLITE_SAVEPOINT +#define org_sqlite_jni_capi_CApi_SQLITE_SAVEPOINT 32L +#undef org_sqlite_jni_capi_CApi_SQLITE_RECURSIVE +#define org_sqlite_jni_capi_CApi_SQLITE_RECURSIVE 33L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATIC +#define org_sqlite_jni_capi_CApi_SQLITE_STATIC 0LL +#undef org_sqlite_jni_capi_CApi_SQLITE_TRANSIENT +#define org_sqlite_jni_capi_CApi_SQLITE_TRANSIENT -1LL +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESETSTART_INVERT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESETSTART_INVERT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_NOSAVEPOINT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_NOSAVEPOINT 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_INVERT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_INVERT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_IGNORENOOP +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_IGNORENOOP 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_DATA +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_DATA 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_NOTFOUND +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_NOTFOUND 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_CONFLICT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_CONFLICT 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_CONSTRAINT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_CONSTRAINT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_FOREIGN_KEY +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_FOREIGN_KEY 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_OMIT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_OMIT 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_REPLACE +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_REPLACE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_ABORT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_ABORT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SINGLETHREAD +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SINGLETHREAD 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MULTITHREAD +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MULTITHREAD 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SERIALIZED +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SERIALIZED 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MALLOC +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MALLOC 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETMALLOC +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETMALLOC 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SCRATCH +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SCRATCH 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PAGECACHE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PAGECACHE 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_HEAP +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_HEAP 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MEMSTATUS +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MEMSTATUS 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MUTEX +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MUTEX 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETMUTEX +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETMUTEX 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_LOOKASIDE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_LOOKASIDE 13L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE 14L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETPCACHE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETPCACHE 15L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_LOG +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_LOG 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_URI +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_URI 17L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE2 +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE2 18L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETPCACHE2 +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETPCACHE2 19L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_COVERING_INDEX_SCAN +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_COVERING_INDEX_SCAN 20L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SQLLOG +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SQLLOG 21L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MMAP_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MMAP_SIZE 22L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_WIN32_HEAPSIZE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_WIN32_HEAPSIZE 23L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE_HDRSZ +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE_HDRSZ 24L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PMASZ +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PMASZ 25L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_STMTJRNL_SPILL +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_STMTJRNL_SPILL 26L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SMALL_MALLOC +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SMALL_MALLOC 27L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SORTERREF_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SORTERREF_SIZE 28L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MEMDB_MAXSIZE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MEMDB_MAXSIZE 29L +#undef org_sqlite_jni_capi_CApi_SQLITE_INTEGER +#define org_sqlite_jni_capi_CApi_SQLITE_INTEGER 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_FLOAT +#define org_sqlite_jni_capi_CApi_SQLITE_FLOAT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_TEXT +#define org_sqlite_jni_capi_CApi_SQLITE_TEXT 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_BLOB +#define org_sqlite_jni_capi_CApi_SQLITE_BLOB 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_NULL +#define org_sqlite_jni_capi_CApi_SQLITE_NULL 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_MAINDBNAME +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_MAINDBNAME 1000L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LOOKASIDE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LOOKASIDE 1001L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_FKEY +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_FKEY 1002L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_TRIGGER 1003L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_QPSG +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_QPSG 1007L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_TRIGGER_EQP +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_TRIGGER_EQP 1008L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_RESET_DATABASE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_RESET_DATABASE 1009L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DEFENSIVE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DEFENSIVE 1010L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_WRITABLE_SCHEMA +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LEGACY_ALTER_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DQS_DML +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DQS_DML 1013L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DQS_DDL +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DQS_DDL 1014L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_VIEW 1015L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LEGACY_FILE_FORMAT +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_TRUSTED_SCHEMA +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_STMT_SCANSTATUS +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_STMT_SCANSTATUS 1018L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_REVERSE_SCANORDER +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_REVERSE_SCANORDER 1019L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_MAX +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_MAX 1019L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_USED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_USED 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_SCHEMA_USED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_SCHEMA_USED 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_STMT_USED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_STMT_USED 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_HIT +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_HIT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_HIT +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_HIT 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_MISS +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_MISS 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_WRITE 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_DEFERRED_FKS +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_DEFERRED_FKS 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF8 +#define org_sqlite_jni_capi_CApi_SQLITE_UTF8 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16LE +#define org_sqlite_jni_capi_CApi_SQLITE_UTF16LE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16BE +#define org_sqlite_jni_capi_CApi_SQLITE_UTF16BE 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16 +#define org_sqlite_jni_capi_CApi_SQLITE_UTF16 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16_ALIGNED +#define org_sqlite_jni_capi_CApi_SQLITE_UTF16_ALIGNED 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LOCKSTATE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LOCKSTATE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_GET_LOCKPROXYFILE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_GET_LOCKPROXYFILE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SET_LOCKPROXYFILE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SET_LOCKPROXYFILE 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LAST_ERRNO +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LAST_ERRNO 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SIZE_HINT +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SIZE_HINT 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CHUNK_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CHUNK_SIZE 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_FILE_POINTER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_FILE_POINTER 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SYNC_OMITTED +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SYNC_OMITTED 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_AV_RETRY +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_AV_RETRY 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PERSIST_WAL +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PERSIST_WAL 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_OVERWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_OVERWRITE 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_VFSNAME +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_VFSNAME 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_POWERSAFE_OVERWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_POWERSAFE_OVERWRITE 13L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PRAGMA +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PRAGMA 14L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_BUSYHANDLER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_BUSYHANDLER 15L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_TEMPFILENAME +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_TEMPFILENAME 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_MMAP_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_MMAP_SIZE 18L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_TRACE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_TRACE 19L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_HAS_MOVED +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_HAS_MOVED 20L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SYNC +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SYNC 21L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_COMMIT_PHASETWO +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_COMMIT_PHASETWO 22L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_SET_HANDLE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_SET_HANDLE 23L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WAL_BLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WAL_BLOCK 24L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_ZIPVFS +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_ZIPVFS 25L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RBU +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RBU 26L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_VFS_POINTER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_VFS_POINTER 27L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_JOURNAL_POINTER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_JOURNAL_POINTER 28L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_GET_HANDLE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_GET_HANDLE 29L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PDB +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PDB 30L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_BEGIN_ATOMIC_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_COMMIT_ATOMIC_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LOCK_TIMEOUT +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LOCK_TIMEOUT 34L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_DATA_VERSION +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_DATA_VERSION 35L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SIZE_LIMIT +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SIZE_LIMIT 36L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKPT_DONE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKPT_DONE 37L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RESERVE_BYTES +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RESERVE_BYTES 38L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKPT_START +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKPT_START 39L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_EXTERNAL_READER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_EXTERNAL_READER 40L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKSM_FILE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKSM_FILE 41L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RESET_CACHE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RESET_CACHE 42L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_NONE +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_NONE 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_SHARED +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_SHARED 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_RESERVED +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_RESERVED 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_PENDING +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_PENDING 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_EXCLUSIVE +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_EXCLUSIVE 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC512 +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC512 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC1K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC1K 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC2K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC2K 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC4K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC4K 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC8K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC8K 32L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC16K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC16K 64L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC32K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC32K 128L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC64K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC64K 256L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_SAFE_APPEND +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_SAFE_APPEND 512L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_SEQUENTIAL +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_SEQUENTIAL 1024L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 2048L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_POWERSAFE_OVERWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_POWERSAFE_OVERWRITE 4096L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_IMMUTABLE +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_IMMUTABLE 8192L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_BATCH_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_BATCH_ATOMIC 16384L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_LENGTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_LENGTH 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_SQL_LENGTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_SQL_LENGTH 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_COLUMN +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_COLUMN 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_EXPR_DEPTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_EXPR_DEPTH 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_COMPOUND_SELECT +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_COMPOUND_SELECT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_VDBE_OP +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_VDBE_OP 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_FUNCTION_ARG +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_FUNCTION_ARG 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_ATTACHED +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_ATTACHED 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_LIKE_PATTERN_LENGTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_VARIABLE_NUMBER +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_VARIABLE_NUMBER 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_TRIGGER_DEPTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_TRIGGER_DEPTH 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_WORKER_THREADS +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_WORKER_THREADS 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_READONLY +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_READONLY 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_READWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_READWRITE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_CREATE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_CREATE 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_URI +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_URI 64L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_MEMORY +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_MEMORY 128L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_NOMUTEX +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_NOMUTEX 32768L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_FULLMUTEX +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_FULLMUTEX 65536L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_SHAREDCACHE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_SHAREDCACHE 131072L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_PRIVATECACHE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_PRIVATECACHE 262144L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_NOFOLLOW +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_NOFOLLOW 16777216L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_EXRESCODE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_EXRESCODE 33554432L +#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_PERSISTENT +#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_PERSISTENT 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NORMALIZE +#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NORMALIZE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NO_VTAB +#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NO_VTAB 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_OK +#define org_sqlite_jni_capi_CApi_SQLITE_OK 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_ERROR +#define org_sqlite_jni_capi_CApi_SQLITE_ERROR 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_INTERNAL +#define org_sqlite_jni_capi_CApi_SQLITE_INTERNAL 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_PERM +#define org_sqlite_jni_capi_CApi_SQLITE_PERM 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_ABORT +#define org_sqlite_jni_capi_CApi_SQLITE_ABORT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_BUSY +#define org_sqlite_jni_capi_CApi_SQLITE_BUSY 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCKED +#define org_sqlite_jni_capi_CApi_SQLITE_LOCKED 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOMEM +#define org_sqlite_jni_capi_CApi_SQLITE_NOMEM 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_INTERRUPT +#define org_sqlite_jni_capi_CApi_SQLITE_INTERRUPT 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_CORRUPT +#define org_sqlite_jni_capi_CApi_SQLITE_CORRUPT 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTFOUND +#define org_sqlite_jni_capi_CApi_SQLITE_NOTFOUND 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_FULL +#define org_sqlite_jni_capi_CApi_SQLITE_FULL 13L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN 14L +#undef org_sqlite_jni_capi_CApi_SQLITE_PROTOCOL +#define org_sqlite_jni_capi_CApi_SQLITE_PROTOCOL 15L +#undef org_sqlite_jni_capi_CApi_SQLITE_EMPTY +#define org_sqlite_jni_capi_CApi_SQLITE_EMPTY 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_SCHEMA +#define org_sqlite_jni_capi_CApi_SQLITE_SCHEMA 17L +#undef org_sqlite_jni_capi_CApi_SQLITE_TOOBIG +#define org_sqlite_jni_capi_CApi_SQLITE_TOOBIG 18L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT 19L +#undef org_sqlite_jni_capi_CApi_SQLITE_MISMATCH +#define org_sqlite_jni_capi_CApi_SQLITE_MISMATCH 20L +#undef org_sqlite_jni_capi_CApi_SQLITE_MISUSE +#define org_sqlite_jni_capi_CApi_SQLITE_MISUSE 21L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOLFS +#define org_sqlite_jni_capi_CApi_SQLITE_NOLFS 22L +#undef org_sqlite_jni_capi_CApi_SQLITE_AUTH +#define org_sqlite_jni_capi_CApi_SQLITE_AUTH 23L +#undef org_sqlite_jni_capi_CApi_SQLITE_FORMAT +#define org_sqlite_jni_capi_CApi_SQLITE_FORMAT 24L +#undef org_sqlite_jni_capi_CApi_SQLITE_RANGE +#define org_sqlite_jni_capi_CApi_SQLITE_RANGE 25L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTADB +#define org_sqlite_jni_capi_CApi_SQLITE_NOTADB 26L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTICE +#define org_sqlite_jni_capi_CApi_SQLITE_NOTICE 27L +#undef org_sqlite_jni_capi_CApi_SQLITE_WARNING +#define org_sqlite_jni_capi_CApi_SQLITE_WARNING 28L +#undef org_sqlite_jni_capi_CApi_SQLITE_ROW +#define org_sqlite_jni_capi_CApi_SQLITE_ROW 100L +#undef org_sqlite_jni_capi_CApi_SQLITE_DONE +#define org_sqlite_jni_capi_CApi_SQLITE_DONE 101L +#undef org_sqlite_jni_capi_CApi_SQLITE_ERROR_MISSING_COLLSEQ +#define org_sqlite_jni_capi_CApi_SQLITE_ERROR_MISSING_COLLSEQ 257L +#undef org_sqlite_jni_capi_CApi_SQLITE_ERROR_RETRY +#define org_sqlite_jni_capi_CApi_SQLITE_ERROR_RETRY 513L +#undef org_sqlite_jni_capi_CApi_SQLITE_ERROR_SNAPSHOT +#define org_sqlite_jni_capi_CApi_SQLITE_ERROR_SNAPSHOT 769L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_READ +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_READ 266L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHORT_READ +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHORT_READ 522L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_WRITE 778L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_FSYNC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_FSYNC 1034L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DIR_FSYNC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DIR_FSYNC 1290L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_TRUNCATE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_TRUNCATE 1546L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_FSTAT +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_FSTAT 1802L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_UNLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_UNLOCK 2058L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_RDLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_RDLOCK 2314L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DELETE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DELETE 2570L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_BLOCKED +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_BLOCKED 2826L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_NOMEM +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_NOMEM 3082L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_ACCESS +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_ACCESS 3338L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_CHECKRESERVEDLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_CHECKRESERVEDLOCK 3594L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_LOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_LOCK 3850L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_CLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_CLOSE 4106L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DIR_CLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DIR_CLOSE 4362L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMOPEN +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMOPEN 4618L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMSIZE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMSIZE 4874L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMLOCK 5130L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMMAP +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMMAP 5386L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SEEK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SEEK 5642L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DELETE_NOENT +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DELETE_NOENT 5898L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_MMAP +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_MMAP 6154L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_GETTEMPPATH +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_GETTEMPPATH 6410L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_CONVPATH +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_CONVPATH 6666L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_VNODE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_VNODE 6922L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_AUTH +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_AUTH 7178L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_BEGIN_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_BEGIN_ATOMIC 7434L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_COMMIT_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_COMMIT_ATOMIC 7690L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_ROLLBACK_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_ROLLBACK_ATOMIC 7946L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DATA +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DATA 8202L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_CORRUPTFS +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_CORRUPTFS 8458L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCKED_SHAREDCACHE +#define org_sqlite_jni_capi_CApi_SQLITE_LOCKED_SHAREDCACHE 262L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCKED_VTAB +#define org_sqlite_jni_capi_CApi_SQLITE_LOCKED_VTAB 518L +#undef org_sqlite_jni_capi_CApi_SQLITE_BUSY_RECOVERY +#define org_sqlite_jni_capi_CApi_SQLITE_BUSY_RECOVERY 261L +#undef org_sqlite_jni_capi_CApi_SQLITE_BUSY_SNAPSHOT +#define org_sqlite_jni_capi_CApi_SQLITE_BUSY_SNAPSHOT 517L +#undef org_sqlite_jni_capi_CApi_SQLITE_BUSY_TIMEOUT +#define org_sqlite_jni_capi_CApi_SQLITE_BUSY_TIMEOUT 773L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_NOTEMPDIR +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_NOTEMPDIR 270L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_ISDIR +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_ISDIR 526L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_FULLPATH +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_FULLPATH 782L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_CONVPATH +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_CONVPATH 1038L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_SYMLINK +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_SYMLINK 1550L +#undef org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_VTAB +#define org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_VTAB 267L +#undef org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_SEQUENCE +#define org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_SEQUENCE 523L +#undef org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_INDEX 779L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_RECOVERY +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_RECOVERY 264L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_CANTLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_CANTLOCK 520L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_ROLLBACK +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_ROLLBACK 776L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_DBMOVED +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_DBMOVED 1032L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_CANTINIT +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_CANTINIT 1288L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_DIRECTORY +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_DIRECTORY 1544L +#undef org_sqlite_jni_capi_CApi_SQLITE_ABORT_ROLLBACK +#define org_sqlite_jni_capi_CApi_SQLITE_ABORT_ROLLBACK 516L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_CHECK +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_CHECK 275L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_COMMITHOOK +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_COMMITHOOK 531L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_FOREIGNKEY +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_FOREIGNKEY 787L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_FUNCTION +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_FUNCTION 1043L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_NOTNULL +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_NOTNULL 1299L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_PRIMARYKEY +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_PRIMARYKEY 1555L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_TRIGGER 1811L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_UNIQUE +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_UNIQUE 2067L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_VTAB +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_VTAB 2323L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_ROWID +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_ROWID 2579L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_PINNED +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_PINNED 2835L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_DATATYPE +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_DATATYPE 3091L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTICE_RECOVER_WAL +#define org_sqlite_jni_capi_CApi_SQLITE_NOTICE_RECOVER_WAL 283L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTICE_RECOVER_ROLLBACK +#define org_sqlite_jni_capi_CApi_SQLITE_NOTICE_RECOVER_ROLLBACK 539L +#undef org_sqlite_jni_capi_CApi_SQLITE_WARNING_AUTOINDEX +#define org_sqlite_jni_capi_CApi_SQLITE_WARNING_AUTOINDEX 284L +#undef org_sqlite_jni_capi_CApi_SQLITE_AUTH_USER +#define org_sqlite_jni_capi_CApi_SQLITE_AUTH_USER 279L +#undef org_sqlite_jni_capi_CApi_SQLITE_OK_LOAD_PERMANENTLY +#define org_sqlite_jni_capi_CApi_SQLITE_OK_LOAD_PERMANENTLY 256L +#undef org_sqlite_jni_capi_CApi_SQLITE_SERIALIZE_NOCOPY +#define org_sqlite_jni_capi_CApi_SQLITE_SERIALIZE_NOCOPY 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_FREEONCLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_FREEONCLOSE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_READONLY +#define org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_READONLY 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_RESIZEABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_RESIZEABLE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_SESSION_CONFIG_STRMSIZE +#define org_sqlite_jni_capi_CApi_SQLITE_SESSION_CONFIG_STRMSIZE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_SESSION_OBJCONFIG_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_SESSION_OBJCONFIG_SIZE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_MEMORY_USED +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_MEMORY_USED 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_USED +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_USED 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_OVERFLOW +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_OVERFLOW 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_MALLOC_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_MALLOC_SIZE 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_PARSER_STACK +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_PARSER_STACK 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_SIZE 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_MALLOC_COUNT +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_MALLOC_COUNT 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FULLSCAN_STEP +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FULLSCAN_STEP 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_SORT +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_SORT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_AUTOINDEX +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_AUTOINDEX 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_VM_STEP +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_VM_STEP 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_REPREPARE +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_REPREPARE 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_RUN +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_RUN 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FILTER_MISS +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FILTER_MISS 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FILTER_HIT +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FILTER_HIT 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_MEMUSED +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_MEMUSED 99L +#undef org_sqlite_jni_capi_CApi_SQLITE_SYNC_NORMAL +#define org_sqlite_jni_capi_CApi_SQLITE_SYNC_NORMAL 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_SYNC_FULL +#define org_sqlite_jni_capi_CApi_SQLITE_SYNC_FULL 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_SYNC_DATAONLY +#define org_sqlite_jni_capi_CApi_SQLITE_SYNC_DATAONLY 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRACE_STMT +#define org_sqlite_jni_capi_CApi_SQLITE_TRACE_STMT 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRACE_PROFILE +#define org_sqlite_jni_capi_CApi_SQLITE_TRACE_PROFILE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRACE_ROW +#define org_sqlite_jni_capi_CApi_SQLITE_TRACE_ROW 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRACE_CLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_TRACE_CLOSE 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_TXN_NONE +#define org_sqlite_jni_capi_CApi_SQLITE_TXN_NONE 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_TXN_READ +#define org_sqlite_jni_capi_CApi_SQLITE_TXN_READ 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_TXN_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_TXN_WRITE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_DETERMINISTIC +#define org_sqlite_jni_capi_CApi_SQLITE_DETERMINISTIC 2048L +#undef org_sqlite_jni_capi_CApi_SQLITE_DIRECTONLY +#define org_sqlite_jni_capi_CApi_SQLITE_DIRECTONLY 524288L +#undef org_sqlite_jni_capi_CApi_SQLITE_INNOCUOUS +#define org_sqlite_jni_capi_CApi_SQLITE_INNOCUOUS 2097152L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_SCAN_UNIQUE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_SCAN_UNIQUE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_EQ +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_EQ 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GT +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LE 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LT +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LT 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GE 32L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_MATCH +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_MATCH 64L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LIKE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LIKE 65L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GLOB +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GLOB 66L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_REGEXP +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_REGEXP 67L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_NE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_NE 68L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNOT +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNOT 69L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNOTNULL +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNULL +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNULL 71L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_IS +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_IS 72L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LIMIT +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LIMIT 73L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_OFFSET +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_OFFSET 74L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_FUNCTION +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_FUNCTION 150L +#undef org_sqlite_jni_capi_CApi_SQLITE_VTAB_CONSTRAINT_SUPPORT +#define org_sqlite_jni_capi_CApi_SQLITE_VTAB_CONSTRAINT_SUPPORT 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_VTAB_INNOCUOUS +#define org_sqlite_jni_capi_CApi_SQLITE_VTAB_INNOCUOUS 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_VTAB_DIRECTONLY +#define org_sqlite_jni_capi_CApi_SQLITE_VTAB_DIRECTONLY 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_VTAB_USES_ALL_SCHEMAS +#define org_sqlite_jni_capi_CApi_SQLITE_VTAB_USES_ALL_SCHEMAS 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_ROLLBACK +#define org_sqlite_jni_capi_CApi_SQLITE_ROLLBACK 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_FAIL +#define org_sqlite_jni_capi_CApi_SQLITE_FAIL 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_REPLACE +#define org_sqlite_jni_capi_CApi_SQLITE_REPLACE 5L /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: init * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_init +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_init (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_java_uncache_thread * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1java_1uncache_1thread +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1java_1uncache_1thread (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_aggregate_context - * Signature: (Lorg/sqlite/jni/sqlite3_context;Z)J + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;Z)J */ -JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1aggregate_1context +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1aggregate_1context (JNIEnv *, jclass, jobject, jboolean); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_auto_extension - * Signature: (Lorg/sqlite/jni/AutoExtensionCallback;)I + * Signature: (Lorg/sqlite/jni/capi/AutoExtensionCallback;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1auto_1extension +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1auto_1extension (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_backup_finish - * Signature: (Lorg/sqlite/jni/sqlite3_backup;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1finish - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1finish + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_backup_init - * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)Lorg/sqlite/jni/sqlite3_backup; + * Signature: (JLjava/lang/String;JLjava/lang/String;)Lorg/sqlite/jni/capi/sqlite3_backup; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1init - (JNIEnv *, jclass, jobject, jstring, jobject, jstring); +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1init + (JNIEnv *, jclass, jlong, jstring, jlong, jstring); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_backup_pagecount - * Signature: (Lorg/sqlite/jni/sqlite3_backup;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1pagecount - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1pagecount + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_backup_remaining - * Signature: (Lorg/sqlite/jni/sqlite3_backup;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1remaining - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1remaining + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_backup_step - * Signature: (Lorg/sqlite/jni/sqlite3_backup;I)I + * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1step - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1step + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_blob - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I[BI)I + * Signature: (JI[BI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1blob - (JNIEnv *, jclass, jobject, jint, jbyteArray, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1blob + (JNIEnv *, jclass, jlong, jint, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_double - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;ID)I + * Signature: (JID)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1double - (JNIEnv *, jclass, jobject, jint, jdouble); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1double + (JNIEnv *, jclass, jlong, jint, jdouble); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_int - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;II)I + * Signature: (JII)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1int - (JNIEnv *, jclass, jobject, jint, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1int + (JNIEnv *, jclass, jlong, jint, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_int64 - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;IJ)I + * Signature: (JIJ)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1int64 - (JNIEnv *, jclass, jobject, jint, jlong); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1int64 + (JNIEnv *, jclass, jlong, jint, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_java_object - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;ILjava/lang/Object;)I + * Signature: (JILjava/lang/Object;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1java_1object - (JNIEnv *, jclass, jobject, jint, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1java_1object + (JNIEnv *, jclass, jlong, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_null - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)I + * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1null - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1null + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_parameter_count - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1parameter_1count - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1parameter_1count + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_parameter_index - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;[B)I + * Signature: (J[B)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1parameter_1index - (JNIEnv *, jclass, jobject, jbyteArray); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1parameter_1index + (JNIEnv *, jclass, jlong, jbyteArray); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_parameter_name - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String; + * Signature: (JI)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1parameter_1name - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1parameter_1name + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_text - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I[BI)I + * Signature: (JI[BI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1text - (JNIEnv *, jclass, jobject, jint, jbyteArray, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1text + (JNIEnv *, jclass, jlong, jint, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_text16 - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I[BI)I + * Signature: (JI[BI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1text16 - (JNIEnv *, jclass, jobject, jint, jbyteArray, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1text16 + (JNIEnv *, jclass, jlong, jint, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_value + * Signature: (JIJ)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1value + (JNIEnv *, jclass, jlong, jint, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_zeroblob - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;II)I + * Signature: (JII)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1zeroblob - (JNIEnv *, jclass, jobject, jint, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1zeroblob + (JNIEnv *, jclass, jlong, jint, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_bind_zeroblob64 - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;IJ)I + * Signature: (JIJ)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1zeroblob64 - (JNIEnv *, jclass, jobject, jint, jlong); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1zeroblob64 + (JNIEnv *, jclass, jlong, jint, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_blob_bytes - * Signature: (Lorg/sqlite/jni/sqlite3_blob;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1bytes - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1bytes + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_blob_close - * Signature: (Lorg/sqlite/jni/sqlite3_blob;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1close - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1close + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_blob_open - * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JILorg/sqlite/jni/OutputPointer/sqlite3_blob;)I + * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JILorg/sqlite/jni/capi/OutputPointer/sqlite3_blob;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1open - (JNIEnv *, jclass, jobject, jstring, jstring, jstring, jlong, jint, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1open + (JNIEnv *, jclass, jlong, jstring, jstring, jstring, jlong, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_blob_read - * Signature: (Lorg/sqlite/jni/sqlite3_blob;[BI)I + * Signature: (J[BI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1read - (JNIEnv *, jclass, jobject, jbyteArray, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1read + (JNIEnv *, jclass, jlong, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_blob_reopen - * Signature: (Lorg/sqlite/jni/sqlite3_blob;J)I + * Signature: (JJ)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1reopen - (JNIEnv *, jclass, jobject, jlong); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1reopen + (JNIEnv *, jclass, jlong, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_blob_write - * Signature: (Lorg/sqlite/jni/sqlite3_blob;[BI)I + * Signature: (J[BI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1write - (JNIEnv *, jclass, jobject, jbyteArray, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1write + (JNIEnv *, jclass, jlong, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_busy_handler - * Signature: (Lorg/sqlite/jni/sqlite3;Lorg/sqlite/jni/BusyHandlerCallback;)I + * Signature: (JLorg/sqlite/jni/capi/BusyHandlerCallback;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1busy_1handler - (JNIEnv *, jclass, jobject, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1busy_1handler + (JNIEnv *, jclass, jlong, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_busy_timeout - * Signature: (Lorg/sqlite/jni/sqlite3;I)I + * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1busy_1timeout - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1busy_1timeout + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_cancel_auto_extension - * Signature: (Lorg/sqlite/jni/AutoExtensionCallback;)Z + * Signature: (Lorg/sqlite/jni/capi/AutoExtensionCallback;)Z */ -JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1cancel_1auto_1extension +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1cancel_1auto_1extension (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_changes - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1changes - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1changes + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_changes64 - * Signature: (Lorg/sqlite/jni/sqlite3;)J + * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1changes64 - (JNIEnv *, jclass, jobject); +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1changes64 + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_clear_bindings - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1clear_1bindings - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1clear_1bindings + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_close - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1close - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1close + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_close_v2 - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1close_1v2 - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1close_1v2 + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_blob - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)[B + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)[B */ -JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1blob +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1blob (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_bytes - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)I + * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1bytes - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1bytes + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_bytes16 - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)I + * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1bytes16 - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1bytes16 + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_count - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1count - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1count + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_decltype + * Signature: (JI)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1decltype + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_double - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)D + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)D */ -JNIEXPORT jdouble JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1double +JNIEXPORT jdouble JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1double (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_int - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1int +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1int (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_int64 - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)J + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)J */ -JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1int64 +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1int64 (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_name - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String; + * Signature: (JI)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1name - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1name + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_database_name - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String; + * Signature: (JI)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1database_1name - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1database_1name + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_origin_name - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String; + * Signature: (JI)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1origin_1name - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1origin_1name + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_table_name - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String; + * Signature: (JI)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1table_1name - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1table_1name + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_text - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)[B + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)[B */ -JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1text +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1text (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_text16 - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String; + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1text16 +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1text16 (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_type - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)I + * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1type - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1type + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_column_value - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Lorg/sqlite/jni/sqlite3_value; + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)Lorg/sqlite/jni/capi/sqlite3_value; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1value +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1value (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_collation_needed - * Signature: (Lorg/sqlite/jni/sqlite3;Lorg/sqlite/jni/CollationNeededCallback;)I + * Signature: (JLorg/sqlite/jni/capi/CollationNeededCallback;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1collation_1needed - (JNIEnv *, jclass, jobject, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1collation_1needed + (JNIEnv *, jclass, jlong, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_commit_hook - * Signature: (Lorg/sqlite/jni/sqlite3;Lorg/sqlite/jni/CommitHookCallback;)Lorg/sqlite/jni/CommitHookCallback; + * Signature: (JLorg/sqlite/jni/capi/CommitHookCallback;)Lorg/sqlite/jni/capi/CommitHookCallback; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1commit_1hook - (JNIEnv *, jclass, jobject, jobject); +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1commit_1hook + (JNIEnv *, jclass, jlong, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_compileoption_get * Signature: (I)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1compileoption_1get +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1compileoption_1get (JNIEnv *, jclass, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_compileoption_used * Signature: (Ljava/lang/String;)Z */ -JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1compileoption_1used +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1compileoption_1used (JNIEnv *, jclass, jstring); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_complete * Signature: ([B)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1complete +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1complete (JNIEnv *, jclass, jbyteArray); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_config * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__I +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__I (JNIEnv *, jclass, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_config - * Signature: (Lorg/sqlite/jni/ConfigSqllogCallback;)I + * Signature: (Lorg/sqlite/jni/capi/ConfigSqllogCallback;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__Lorg_sqlite_jni_ConfigSqllogCallback_2 +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__Lorg_sqlite_jni_capi_ConfigSqllogCallback_2 (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_config - * Signature: (Lorg/sqlite/jni/ConfigLogCallback;)I + * Signature: (Lorg/sqlite/jni/capi/ConfigLogCallback;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__Lorg_sqlite_jni_ConfigLogCallback_2 +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__Lorg_sqlite_jni_capi_ConfigLogCallback_2 (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_context_db_handle - * Signature: (Lorg/sqlite/jni/sqlite3_context;)Lorg/sqlite/jni/sqlite3; + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)Lorg/sqlite/jni/capi/sqlite3; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1context_1db_1handle +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1context_1db_1handle (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_create_collation - * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;ILorg/sqlite/jni/CollationCallback;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;ILorg/sqlite/jni/capi/CollationCallback;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1create_1collation +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1create_1collation (JNIEnv *, jclass, jobject, jstring, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_create_function - * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;IILorg/sqlite/jni/SQLFunction;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;IILorg/sqlite/jni/capi/SQLFunction;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1create_1function +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1create_1function (JNIEnv *, jclass, jobject, jstring, jint, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_data_count - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1data_1count - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1data_1count + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_db_config - * Signature: (Lorg/sqlite/jni/sqlite3;IILorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;IILorg/sqlite/jni/capi/OutputPointer/Int32;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPointer_00024Int32_2 +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_Int32_2 (JNIEnv *, jclass, jobject, jint, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_db_config - * Signature: (Lorg/sqlite/jni/sqlite3;ILjava/lang/String;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;ILjava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1config__Lorg_sqlite_jni_sqlite3_2ILjava_lang_String_2 +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_capi_sqlite3_2ILjava_lang_String_2 (JNIEnv *, jclass, jobject, jint, jstring); /* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_db_filename - * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)Ljava/lang/String; + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_name + * Signature: (JI)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1filename +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1name + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_filename + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1filename (JNIEnv *, jclass, jobject, jstring); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_db_handle - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)Lorg/sqlite/jni/sqlite3; + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Lorg/sqlite/jni/capi/sqlite3; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1handle +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1handle (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_readonly + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1readonly + (JNIEnv *, jclass, jobject, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_db_release_memory - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1release_1memory +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1release_1memory (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_db_status - * Signature: (Lorg/sqlite/jni/sqlite3;ILorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;Z)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;ILorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;Z)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1status +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1status (JNIEnv *, jclass, jobject, jint, jobject, jobject, jboolean); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_errcode - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errcode +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1errcode (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_errmsg16 - * Signature: (Lorg/sqlite/jni/sqlite3;)Ljava/lang/String; + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_errmsg + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errmsg16 +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1errmsg (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_error_offset + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1error_1offset + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_errstr * Signature: (I)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errstr +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1errstr (JNIEnv *, jclass, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_expanded_sql - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)Ljava/lang/String; + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1expanded_1sql +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1expanded_1sql (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_extended_errcode - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1extended_1errcode - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1extended_1errcode + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_extended_result_codes - * Signature: (Lorg/sqlite/jni/sqlite3;Z)Z + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Z)Z */ -JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1extended_1result_1codes +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1extended_1result_1codes (JNIEnv *, jclass, jobject, jboolean); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_get_autocommit - * Signature: (Lorg/sqlite/jni/sqlite3;)Z + * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1get_1autocommit - (JNIEnv *, jclass, jobject); +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1get_1autocommit + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_get_auxdata - * Signature: (Lorg/sqlite/jni/sqlite3_context;I)Ljava/lang/Object; + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)Ljava/lang/Object; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1get_1auxdata +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1get_1auxdata (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_error_offset - * Signature: (Lorg/sqlite/jni/sqlite3;)I - */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1error_1offset - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_finalize - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1finalize - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1finalize + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_initialize * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1initialize +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1initialize (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_interrupt - * Signature: (Lorg/sqlite/jni/sqlite3;)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1interrupt +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1interrupt (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_is_interrupted - * Signature: (Lorg/sqlite/jni/sqlite3;)Z + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)Z */ -JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1is_1interrupted +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1is_1interrupted (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_keyword_check * Signature: (Ljava/lang/String;)Z */ -JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1keyword_1check +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1keyword_1check (JNIEnv *, jclass, jstring); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_keyword_count * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1keyword_1count +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1keyword_1count (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_keyword_name * Signature: (I)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1keyword_1name +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1keyword_1name (JNIEnv *, jclass, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_last_insert_rowid - * Signature: (Lorg/sqlite/jni/sqlite3;)J + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)J */ -JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1last_1insert_1rowid +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1last_1insert_1rowid (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_libversion * Signature: ()Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1libversion +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1libversion (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_libversion_number * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1libversion_1number +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1libversion_1number (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_limit - * Signature: (Lorg/sqlite/jni/sqlite3;II)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;II)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1limit +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1limit (JNIEnv *, jclass, jobject, jint, jint); /* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_open - * Signature: (Ljava/lang/String;Lorg/sqlite/jni/OutputPointer/sqlite3;)I + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_normalized_sql + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Ljava/lang/String; */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1open +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1normalized_1sql + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_open + * Signature: (Ljava/lang/String;Lorg/sqlite/jni/capi/OutputPointer/sqlite3;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1open (JNIEnv *, jclass, jstring, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_open_v2 - * Signature: (Ljava/lang/String;Lorg/sqlite/jni/OutputPointer/sqlite3;ILjava/lang/String;)I + * Signature: (Ljava/lang/String;Lorg/sqlite/jni/capi/OutputPointer/sqlite3;ILjava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1open_1v2 +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1open_1v2 (JNIEnv *, jclass, jstring, jobject, jint, jstring); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_prepare - * Signature: (Lorg/sqlite/jni/sqlite3;[BILorg/sqlite/jni/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (J[BILorg/sqlite/jni/capi/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1prepare - (JNIEnv *, jclass, jobject, jbyteArray, jint, jobject, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1prepare + (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_prepare_v2 - * Signature: (Lorg/sqlite/jni/sqlite3;[BILorg/sqlite/jni/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (J[BILorg/sqlite/jni/capi/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1prepare_1v2 - (JNIEnv *, jclass, jobject, jbyteArray, jint, jobject, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1prepare_1v2 + (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_prepare_v3 - * Signature: (Lorg/sqlite/jni/sqlite3;[BIILorg/sqlite/jni/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (J[BIILorg/sqlite/jni/capi/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1prepare_1v3 - (JNIEnv *, jclass, jobject, jbyteArray, jint, jint, jobject, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1prepare_1v3 + (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jobject, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_preupdate_blobwrite - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1preupdate_1blobwrite - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1blobwrite + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_preupdate_count - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1preupdate_1count - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1count + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_preupdate_depth - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1preupdate_1depth - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1depth + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_preupdate_hook - * Signature: (Lorg/sqlite/jni/sqlite3;Lorg/sqlite/jni/PreupdateHookCallback;)Lorg/sqlite/jni/PreupdateHookCallback; + * Signature: (JLorg/sqlite/jni/capi/PreupdateHookCallback;)Lorg/sqlite/jni/capi/PreupdateHookCallback; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1preupdate_1hook - (JNIEnv *, jclass, jobject, jobject); +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1hook + (JNIEnv *, jclass, jlong, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_preupdate_new - * Signature: (Lorg/sqlite/jni/sqlite3;ILorg/sqlite/jni/OutputPointer/sqlite3_value;)I + * Signature: (JILorg/sqlite/jni/capi/OutputPointer/sqlite3_value;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1preupdate_1new - (JNIEnv *, jclass, jobject, jint, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1new + (JNIEnv *, jclass, jlong, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_preupdate_old - * Signature: (Lorg/sqlite/jni/sqlite3;ILorg/sqlite/jni/OutputPointer/sqlite3_value;)I + * Signature: (JILorg/sqlite/jni/capi/OutputPointer/sqlite3_value;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1preupdate_1old - (JNIEnv *, jclass, jobject, jint, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1old + (JNIEnv *, jclass, jlong, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_progress_handler - * Signature: (Lorg/sqlite/jni/sqlite3;ILorg/sqlite/jni/ProgressHandlerCallback;)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3;ILorg/sqlite/jni/capi/ProgressHandlerCallback;)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1progress_1handler +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1progress_1handler (JNIEnv *, jclass, jobject, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_randomness * Signature: ([B)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1randomness +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1randomness (JNIEnv *, jclass, jbyteArray); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_release_memory * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1release_1memory +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1release_1memory (JNIEnv *, jclass, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_reset - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1reset +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1reset (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_reset_auto_extension * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1reset_1auto_1extension +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1reset_1auto_1extension (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_double - * Signature: (Lorg/sqlite/jni/sqlite3_context;D)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;D)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1double +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1double (JNIEnv *, jclass, jobject, jdouble); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_error - * Signature: (Lorg/sqlite/jni/sqlite3_context;[BI)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BI)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1error +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error (JNIEnv *, jclass, jobject, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_error_toobig - * Signature: (Lorg/sqlite/jni/sqlite3_context;)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1error_1toobig +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error_1toobig (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_error_nomem - * Signature: (Lorg/sqlite/jni/sqlite3_context;)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1error_1nomem +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error_1nomem (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_error_code - * Signature: (Lorg/sqlite/jni/sqlite3_context;I)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1error_1code +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error_1code (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_null - * Signature: (Lorg/sqlite/jni/sqlite3_context;)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1null +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1null (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_int - * Signature: (Lorg/sqlite/jni/sqlite3_context;I)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1int +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1int (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_int64 - * Signature: (Lorg/sqlite/jni/sqlite3_context;J)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;J)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1int64 +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1int64 (JNIEnv *, jclass, jobject, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_java_object - * Signature: (Lorg/sqlite/jni/sqlite3_context;Ljava/lang/Object;)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;Ljava/lang/Object;)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1java_1object +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1java_1object (JNIEnv *, jclass, jobject, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_value - * Signature: (Lorg/sqlite/jni/sqlite3_context;Lorg/sqlite/jni/sqlite3_value;)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;Lorg/sqlite/jni/capi/sqlite3_value;)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1value +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1value (JNIEnv *, jclass, jobject, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_zeroblob - * Signature: (Lorg/sqlite/jni/sqlite3_context;I)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1zeroblob +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1zeroblob (JNIEnv *, jclass, jobject, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_zeroblob64 - * Signature: (Lorg/sqlite/jni/sqlite3_context;J)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1zeroblob64 +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1zeroblob64 (JNIEnv *, jclass, jobject, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_blob - * Signature: (Lorg/sqlite/jni/sqlite3_context;[BI)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BI)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1blob +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1blob (JNIEnv *, jclass, jobject, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_blob64 - * Signature: (Lorg/sqlite/jni/sqlite3_context;[BJ)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BJ)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1blob64 +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1blob64 (JNIEnv *, jclass, jobject, jbyteArray, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_text - * Signature: (Lorg/sqlite/jni/sqlite3_context;[BI)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BI)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1text +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1text (JNIEnv *, jclass, jobject, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_text64 - * Signature: (Lorg/sqlite/jni/sqlite3_context;[BJI)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BJI)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1result_1text64 +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1text64 (JNIEnv *, jclass, jobject, jbyteArray, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_rollback_hook - * Signature: (Lorg/sqlite/jni/sqlite3;Lorg/sqlite/jni/RollbackHookCallback;)Lorg/sqlite/jni/RollbackHookCallback; + * Signature: (JLorg/sqlite/jni/capi/RollbackHookCallback;)Lorg/sqlite/jni/capi/RollbackHookCallback; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1rollback_1hook - (JNIEnv *, jclass, jobject, jobject); +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1rollback_1hook + (JNIEnv *, jclass, jlong, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_set_authorizer - * Signature: (Lorg/sqlite/jni/sqlite3;Lorg/sqlite/jni/AuthorizerCallback;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Lorg/sqlite/jni/capi/AuthorizerCallback;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1set_1authorizer +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1set_1authorizer (JNIEnv *, jclass, jobject, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_set_auxdata - * Signature: (Lorg/sqlite/jni/sqlite3_context;ILjava/lang/Object;)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;ILjava/lang/Object;)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1set_1auxdata +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1set_1auxdata (JNIEnv *, jclass, jobject, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_set_last_insert_rowid - * Signature: (Lorg/sqlite/jni/sqlite3;J)V + * Signature: (Lorg/sqlite/jni/capi/sqlite3;J)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1set_1last_1insert_1rowid +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1set_1last_1insert_1rowid (JNIEnv *, jclass, jobject, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_shutdown * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1shutdown +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1shutdown (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_sleep * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1sleep +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1sleep (JNIEnv *, jclass, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_sourceid * Signature: ()Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1sourceid +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1sourceid (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_sql - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)Ljava/lang/String; + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1sql +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1sql (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_status - * Signature: (ILorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;Z)I + * Signature: (ILorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;Z)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1status +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1status (JNIEnv *, jclass, jint, jobject, jobject, jboolean); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_status64 - * Signature: (ILorg/sqlite/jni/OutputPointer/Int64;Lorg/sqlite/jni/OutputPointer/Int64;Z)I + * Signature: (ILorg/sqlite/jni/capi/OutputPointer/Int64;Lorg/sqlite/jni/capi/OutputPointer/Int64;Z)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1status64 +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1status64 (JNIEnv *, jclass, jint, jobject, jobject, jboolean); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_step - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1step +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1step (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_stmt_busy + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1busy + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_stmt_explain - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)I + * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1stmt_1explain - (JNIEnv *, jclass, jobject, jint); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1explain + (JNIEnv *, jclass, jlong, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_stmt_isexplain - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1stmt_1isexplain - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1isexplain + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_stmt_readonly - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;)Z + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Z */ -JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1stmt_1readonly +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1readonly (JNIEnv *, jclass, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_stmt_status - * Signature: (Lorg/sqlite/jni/sqlite3_stmt;IZ)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;IZ)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1stmt_1status +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1status (JNIEnv *, jclass, jobject, jint, jboolean); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_strglob * Signature: ([B[B)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1strglob +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1strglob (JNIEnv *, jclass, jbyteArray, jbyteArray); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_strlike * Signature: ([B[BI)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1strlike +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1strlike (JNIEnv *, jclass, jbyteArray, jbyteArray, jint); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_system_errno - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1system_1errno - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1system_1errno + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_table_column_metadata - * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/sqlite/jni/OutputPointer/String;Lorg/sqlite/jni/OutputPointer/String;Lorg/sqlite/jni/OutputPointer/Bool;Lorg/sqlite/jni/OutputPointer/Bool;Lorg/sqlite/jni/OutputPointer/Bool;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/sqlite/jni/capi/OutputPointer/String;Lorg/sqlite/jni/capi/OutputPointer/String;Lorg/sqlite/jni/capi/OutputPointer/Bool;Lorg/sqlite/jni/capi/OutputPointer/Bool;Lorg/sqlite/jni/capi/OutputPointer/Bool;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1table_1column_1metadata +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1table_1column_1metadata (JNIEnv *, jclass, jobject, jstring, jstring, jstring, jobject, jobject, jobject, jobject, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_threadsafe * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1threadsafe +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1threadsafe (JNIEnv *, jclass); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_total_changes - * Signature: (Lorg/sqlite/jni/sqlite3;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1total_1changes - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1total_1changes + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_total_changes64 - * Signature: (Lorg/sqlite/jni/sqlite3;)J + * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1total_1changes64 - (JNIEnv *, jclass, jobject); +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1total_1changes64 + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_trace_v2 - * Signature: (Lorg/sqlite/jni/sqlite3;ILorg/sqlite/jni/TraceV2Callback;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;ILorg/sqlite/jni/capi/TraceV2Callback;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1trace_1v2 +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1trace_1v2 (JNIEnv *, jclass, jobject, jint, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_txn_state - * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)I + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1txn_1state +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1txn_1state (JNIEnv *, jclass, jobject, jstring); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_update_hook - * Signature: (Lorg/sqlite/jni/sqlite3;Lorg/sqlite/jni/UpdateHookCallback;)Lorg/sqlite/jni/UpdateHookCallback; + * Signature: (JLorg/sqlite/jni/capi/UpdateHookCallback;)Lorg/sqlite/jni/capi/UpdateHookCallback; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1update_1hook - (JNIEnv *, jclass, jobject, jobject); +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1update_1hook + (JNIEnv *, jclass, jlong, jobject); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_blob - * Signature: (Lorg/sqlite/jni/sqlite3_value;)[B + * Signature: (J)[B */ -JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1blob - (JNIEnv *, jclass, jobject); +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1blob + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_bytes - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1bytes - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1bytes + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_bytes16 - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1bytes16 - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1bytes16 + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_double - * Signature: (Lorg/sqlite/jni/sqlite3_value;)D + * Signature: (J)D */ -JNIEXPORT jdouble JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1double - (JNIEnv *, jclass, jobject); +JNIEXPORT jdouble JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1double + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_dup - * Signature: (Lorg/sqlite/jni/sqlite3_value;)Lorg/sqlite/jni/sqlite3_value; + * Signature: (J)Lorg/sqlite/jni/capi/sqlite3_value; */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1dup - (JNIEnv *, jclass, jobject); +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1dup + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_encoding - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1encoding - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1encoding + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_free - * Signature: (Lorg/sqlite/jni/sqlite3_value;)V + * Signature: (J)V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1free - (JNIEnv *, jclass, jobject); +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1free + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_value_int - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I - */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1int - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_value_int64 - * Signature: (Lorg/sqlite/jni/sqlite3_value;)J - */ -JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1int64 - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_value_java_object - * Signature: (Lorg/sqlite/jni/sqlite3_value;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1java_1object - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_value_text - * Signature: (Lorg/sqlite/jni/sqlite3_value;)[B - */ -JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_value_text16 - * Signature: (Lorg/sqlite/jni/sqlite3_value;)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text16 - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_value_type - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I - */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1type - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_value_numeric_type - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I - */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1numeric_1type - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni - * Method: sqlite3_value_nochange - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I - */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1nochange - (JNIEnv *, jclass, jobject); - -/* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_frombind - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I + * Signature: (J)Z */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1frombind - (JNIEnv *, jclass, jobject); +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1frombind + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_int + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1int + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_int64 + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1int64 + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_java_object + * Signature: (J)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1java_1object + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_nochange + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1nochange + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_numeric_type + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1numeric_1type + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_value_subtype - * Signature: (Lorg/sqlite/jni/sqlite3_value;)I + * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1subtype - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1subtype + (JNIEnv *, jclass, jlong); /* - * Class: org_sqlite_jni_SQLite3Jni + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_text + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1text + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_text16 + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1text16 + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_type + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1type + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_jni_internal_details * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1jni_1internal_1details +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1jni_1internal_1details + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_sqlite_jni_capi_SQLTester */ + +#ifndef _Included_org_sqlite_jni_capi_SQLTester +#define _Included_org_sqlite_jni_capi_SQLTester +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_sqlite_jni_capi_SQLTester + * Method: strglob + * Signature: ([B[B)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_SQLTester_strglob + (JNIEnv *, jclass, jbyteArray, jbyteArray); + +/* + * Class: org_sqlite_jni_capi_SQLTester + * Method: installCustomExtensions + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_SQLTester_installCustomExtensions (JNIEnv *, jclass); #ifdef __cplusplus @@ -2123,7 +2180,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnCount /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xColumnSize - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/capi/OutputPointer/Int32;)I */ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnSize (JNIEnv *, jobject, jobject, jint, jobject); @@ -2131,7 +2188,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnSize /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xColumnText - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/OutputPointer/String;)I + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/capi/OutputPointer/String;)I */ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnText (JNIEnv *, jobject, jobject, jint, jobject); @@ -2139,7 +2196,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnText /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xColumnTotalSize - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/OutputPointer/Int64;)I + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/capi/OutputPointer/Int64;)I */ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnTotalSize (JNIEnv *, jobject, jobject, jint, jobject); @@ -2155,7 +2212,7 @@ JNIEXPORT jobject JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xGetAuxdata /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xInst - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I */ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xInst (JNIEnv *, jobject, jobject, jint, jobject, jobject, jobject); @@ -2163,7 +2220,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xInst /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xInstCount - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I */ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xInstCount (JNIEnv *, jobject, jobject, jobject); @@ -2179,7 +2236,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseCount /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xPhraseFirst - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I */ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseFirst (JNIEnv *, jobject, jobject, jint, jobject, jobject, jobject); @@ -2187,7 +2244,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseFirst /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xPhraseFirstColumn - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;)I + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I */ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseFirstColumn (JNIEnv *, jobject, jobject, jint, jobject, jobject); @@ -2195,7 +2252,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseFirstCol /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xPhraseNext - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;)V + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;)V */ JNIEXPORT void JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseNext (JNIEnv *, jobject, jobject, jobject, jobject, jobject); @@ -2203,7 +2260,7 @@ JNIEXPORT void JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseNext /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xPhraseNextColumn - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;)V + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/capi/OutputPointer/Int32;)V */ JNIEXPORT void JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseNextColumn (JNIEnv *, jobject, jobject, jobject, jobject); @@ -2227,7 +2284,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xQueryPhrase /* * Class: org_sqlite_jni_fts5_Fts5ExtensionApi * Method: xRowCount - * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/OutputPointer/Int64;)I + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/capi/OutputPointer/Int64;)I */ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xRowCount (JNIEnv *, jobject, jobject, jobject); @@ -2282,7 +2339,7 @@ extern "C" { /* * Class: org_sqlite_jni_fts5_fts5_api * Method: getInstanceForDb - * Signature: (Lorg/sqlite/jni/sqlite3;)Lorg/sqlite/jni/fts5/fts5_api; + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)Lorg/sqlite/jni/fts5/fts5_api; */ JNIEXPORT jobject JNICALL Java_org_sqlite_jni_fts5_fts5_1api_getInstanceForDb (JNIEnv *, jclass, jobject); @@ -2320,32 +2377,3 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_fts5_1tokenizer_xTokenize } #endif #endif -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class org_sqlite_jni_tester_SQLTester */ - -#ifndef _Included_org_sqlite_jni_tester_SQLTester -#define _Included_org_sqlite_jni_tester_SQLTester -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_sqlite_jni_tester_SQLTester - * Method: strglob - * Signature: ([B[B)I - */ -JNIEXPORT jint JNICALL Java_org_sqlite_jni_tester_SQLTester_strglob - (JNIEnv *, jclass, jbyteArray, jbyteArray); - -/* - * Class: org_sqlite_jni_tester_SQLTester - * Method: installCustomExtensions - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_sqlite_jni_tester_SQLTester_installCustomExtensions - (JNIEnv *, jclass); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ext/jni/src/org/sqlite/jni/ResultCode.java b/ext/jni/src/org/sqlite/jni/ResultCode.java deleted file mode 100644 index 0989bc744d..0000000000 --- a/ext/jni/src/org/sqlite/jni/ResultCode.java +++ /dev/null @@ -1,155 +0,0 @@ -/* -** 2023-07-21 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file is part of the JNI bindings for the sqlite3 C API. -*/ -package org.sqlite.jni; - -/** - This enum contains all of the core and "extended" result codes used - by the sqlite3 library. It is provided not for use with the C-style - API (with which it won't work) but for higher-level code which may - find it useful to map SQLite result codes to human-readable names. -*/ -public enum ResultCode { - SQLITE_OK(SQLite3Jni.SQLITE_OK), - SQLITE_ERROR(SQLite3Jni.SQLITE_ERROR), - SQLITE_INTERNAL(SQLite3Jni.SQLITE_INTERNAL), - SQLITE_PERM(SQLite3Jni.SQLITE_PERM), - SQLITE_ABORT(SQLite3Jni.SQLITE_ABORT), - SQLITE_BUSY(SQLite3Jni.SQLITE_BUSY), - SQLITE_LOCKED(SQLite3Jni.SQLITE_LOCKED), - SQLITE_NOMEM(SQLite3Jni.SQLITE_NOMEM), - SQLITE_READONLY(SQLite3Jni.SQLITE_READONLY), - SQLITE_INTERRUPT(SQLite3Jni.SQLITE_INTERRUPT), - SQLITE_IOERR(SQLite3Jni.SQLITE_IOERR), - SQLITE_CORRUPT(SQLite3Jni.SQLITE_CORRUPT), - SQLITE_NOTFOUND(SQLite3Jni.SQLITE_NOTFOUND), - SQLITE_FULL(SQLite3Jni.SQLITE_FULL), - SQLITE_CANTOPEN(SQLite3Jni.SQLITE_CANTOPEN), - SQLITE_PROTOCOL(SQLite3Jni.SQLITE_PROTOCOL), - SQLITE_EMPTY(SQLite3Jni.SQLITE_EMPTY), - SQLITE_SCHEMA(SQLite3Jni.SQLITE_SCHEMA), - SQLITE_TOOBIG(SQLite3Jni.SQLITE_TOOBIG), - SQLITE_CONSTRAINT(SQLite3Jni.SQLITE_CONSTRAINT), - SQLITE_MISMATCH(SQLite3Jni.SQLITE_MISMATCH), - SQLITE_MISUSE(SQLite3Jni.SQLITE_MISUSE), - SQLITE_NOLFS(SQLite3Jni.SQLITE_NOLFS), - SQLITE_AUTH(SQLite3Jni.SQLITE_AUTH), - SQLITE_FORMAT(SQLite3Jni.SQLITE_FORMAT), - SQLITE_RANGE(SQLite3Jni.SQLITE_RANGE), - SQLITE_NOTADB(SQLite3Jni.SQLITE_NOTADB), - SQLITE_NOTICE(SQLite3Jni.SQLITE_NOTICE), - SQLITE_WARNING(SQLite3Jni.SQLITE_WARNING), - SQLITE_ROW(SQLite3Jni.SQLITE_ROW), - SQLITE_DONE(SQLite3Jni.SQLITE_DONE), - SQLITE_ERROR_MISSING_COLLSEQ(SQLite3Jni.SQLITE_ERROR_MISSING_COLLSEQ), - SQLITE_ERROR_RETRY(SQLite3Jni.SQLITE_ERROR_RETRY), - SQLITE_ERROR_SNAPSHOT(SQLite3Jni.SQLITE_ERROR_SNAPSHOT), - SQLITE_IOERR_READ(SQLite3Jni.SQLITE_IOERR_READ), - SQLITE_IOERR_SHORT_READ(SQLite3Jni.SQLITE_IOERR_SHORT_READ), - SQLITE_IOERR_WRITE(SQLite3Jni.SQLITE_IOERR_WRITE), - SQLITE_IOERR_FSYNC(SQLite3Jni.SQLITE_IOERR_FSYNC), - SQLITE_IOERR_DIR_FSYNC(SQLite3Jni.SQLITE_IOERR_DIR_FSYNC), - SQLITE_IOERR_TRUNCATE(SQLite3Jni.SQLITE_IOERR_TRUNCATE), - SQLITE_IOERR_FSTAT(SQLite3Jni.SQLITE_IOERR_FSTAT), - SQLITE_IOERR_UNLOCK(SQLite3Jni.SQLITE_IOERR_UNLOCK), - SQLITE_IOERR_RDLOCK(SQLite3Jni.SQLITE_IOERR_RDLOCK), - SQLITE_IOERR_DELETE(SQLite3Jni.SQLITE_IOERR_DELETE), - SQLITE_IOERR_BLOCKED(SQLite3Jni.SQLITE_IOERR_BLOCKED), - SQLITE_IOERR_NOMEM(SQLite3Jni.SQLITE_IOERR_NOMEM), - SQLITE_IOERR_ACCESS(SQLite3Jni.SQLITE_IOERR_ACCESS), - SQLITE_IOERR_CHECKRESERVEDLOCK(SQLite3Jni.SQLITE_IOERR_CHECKRESERVEDLOCK), - SQLITE_IOERR_LOCK(SQLite3Jni.SQLITE_IOERR_LOCK), - SQLITE_IOERR_CLOSE(SQLite3Jni.SQLITE_IOERR_CLOSE), - SQLITE_IOERR_DIR_CLOSE(SQLite3Jni.SQLITE_IOERR_DIR_CLOSE), - SQLITE_IOERR_SHMOPEN(SQLite3Jni.SQLITE_IOERR_SHMOPEN), - SQLITE_IOERR_SHMSIZE(SQLite3Jni.SQLITE_IOERR_SHMSIZE), - SQLITE_IOERR_SHMLOCK(SQLite3Jni.SQLITE_IOERR_SHMLOCK), - SQLITE_IOERR_SHMMAP(SQLite3Jni.SQLITE_IOERR_SHMMAP), - SQLITE_IOERR_SEEK(SQLite3Jni.SQLITE_IOERR_SEEK), - SQLITE_IOERR_DELETE_NOENT(SQLite3Jni.SQLITE_IOERR_DELETE_NOENT), - SQLITE_IOERR_MMAP(SQLite3Jni.SQLITE_IOERR_MMAP), - SQLITE_IOERR_GETTEMPPATH(SQLite3Jni.SQLITE_IOERR_GETTEMPPATH), - SQLITE_IOERR_CONVPATH(SQLite3Jni.SQLITE_IOERR_CONVPATH), - SQLITE_IOERR_VNODE(SQLite3Jni.SQLITE_IOERR_VNODE), - SQLITE_IOERR_AUTH(SQLite3Jni.SQLITE_IOERR_AUTH), - SQLITE_IOERR_BEGIN_ATOMIC(SQLite3Jni.SQLITE_IOERR_BEGIN_ATOMIC), - SQLITE_IOERR_COMMIT_ATOMIC(SQLite3Jni.SQLITE_IOERR_COMMIT_ATOMIC), - SQLITE_IOERR_ROLLBACK_ATOMIC(SQLite3Jni.SQLITE_IOERR_ROLLBACK_ATOMIC), - SQLITE_IOERR_DATA(SQLite3Jni.SQLITE_IOERR_DATA), - SQLITE_IOERR_CORRUPTFS(SQLite3Jni.SQLITE_IOERR_CORRUPTFS), - SQLITE_LOCKED_SHAREDCACHE(SQLite3Jni.SQLITE_LOCKED_SHAREDCACHE), - SQLITE_LOCKED_VTAB(SQLite3Jni.SQLITE_LOCKED_VTAB), - SQLITE_BUSY_RECOVERY(SQLite3Jni.SQLITE_BUSY_RECOVERY), - SQLITE_BUSY_SNAPSHOT(SQLite3Jni.SQLITE_BUSY_SNAPSHOT), - SQLITE_BUSY_TIMEOUT(SQLite3Jni.SQLITE_BUSY_TIMEOUT), - SQLITE_CANTOPEN_NOTEMPDIR(SQLite3Jni.SQLITE_CANTOPEN_NOTEMPDIR), - SQLITE_CANTOPEN_ISDIR(SQLite3Jni.SQLITE_CANTOPEN_ISDIR), - SQLITE_CANTOPEN_FULLPATH(SQLite3Jni.SQLITE_CANTOPEN_FULLPATH), - SQLITE_CANTOPEN_CONVPATH(SQLite3Jni.SQLITE_CANTOPEN_CONVPATH), - SQLITE_CANTOPEN_SYMLINK(SQLite3Jni.SQLITE_CANTOPEN_SYMLINK), - SQLITE_CORRUPT_VTAB(SQLite3Jni.SQLITE_CORRUPT_VTAB), - SQLITE_CORRUPT_SEQUENCE(SQLite3Jni.SQLITE_CORRUPT_SEQUENCE), - SQLITE_CORRUPT_INDEX(SQLite3Jni.SQLITE_CORRUPT_INDEX), - SQLITE_READONLY_RECOVERY(SQLite3Jni.SQLITE_READONLY_RECOVERY), - SQLITE_READONLY_CANTLOCK(SQLite3Jni.SQLITE_READONLY_CANTLOCK), - SQLITE_READONLY_ROLLBACK(SQLite3Jni.SQLITE_READONLY_ROLLBACK), - SQLITE_READONLY_DBMOVED(SQLite3Jni.SQLITE_READONLY_DBMOVED), - SQLITE_READONLY_CANTINIT(SQLite3Jni.SQLITE_READONLY_CANTINIT), - SQLITE_READONLY_DIRECTORY(SQLite3Jni.SQLITE_READONLY_DIRECTORY), - SQLITE_ABORT_ROLLBACK(SQLite3Jni.SQLITE_ABORT_ROLLBACK), - SQLITE_CONSTRAINT_CHECK(SQLite3Jni.SQLITE_CONSTRAINT_CHECK), - SQLITE_CONSTRAINT_COMMITHOOK(SQLite3Jni.SQLITE_CONSTRAINT_COMMITHOOK), - SQLITE_CONSTRAINT_FOREIGNKEY(SQLite3Jni.SQLITE_CONSTRAINT_FOREIGNKEY), - SQLITE_CONSTRAINT_FUNCTION(SQLite3Jni.SQLITE_CONSTRAINT_FUNCTION), - SQLITE_CONSTRAINT_NOTNULL(SQLite3Jni.SQLITE_CONSTRAINT_NOTNULL), - SQLITE_CONSTRAINT_PRIMARYKEY(SQLite3Jni.SQLITE_CONSTRAINT_PRIMARYKEY), - SQLITE_CONSTRAINT_TRIGGER(SQLite3Jni.SQLITE_CONSTRAINT_TRIGGER), - SQLITE_CONSTRAINT_UNIQUE(SQLite3Jni.SQLITE_CONSTRAINT_UNIQUE), - SQLITE_CONSTRAINT_VTAB(SQLite3Jni.SQLITE_CONSTRAINT_VTAB), - SQLITE_CONSTRAINT_ROWID(SQLite3Jni.SQLITE_CONSTRAINT_ROWID), - SQLITE_CONSTRAINT_PINNED(SQLite3Jni.SQLITE_CONSTRAINT_PINNED), - SQLITE_CONSTRAINT_DATATYPE(SQLite3Jni.SQLITE_CONSTRAINT_DATATYPE), - SQLITE_NOTICE_RECOVER_WAL(SQLite3Jni.SQLITE_NOTICE_RECOVER_WAL), - SQLITE_NOTICE_RECOVER_ROLLBACK(SQLite3Jni.SQLITE_NOTICE_RECOVER_ROLLBACK), - SQLITE_WARNING_AUTOINDEX(SQLite3Jni.SQLITE_WARNING_AUTOINDEX), - SQLITE_AUTH_USER(SQLite3Jni.SQLITE_AUTH_USER), - SQLITE_OK_LOAD_PERMANENTLY(SQLite3Jni.SQLITE_OK_LOAD_PERMANENTLY); - - public final int value; - - ResultCode(int rc){ - value = rc; - ResultCodeMap.set(rc, this); - } - - /** - Returns the entry from this enum for the given result code, or - null if no match is found. - */ - public static ResultCode getEntryForInt(int rc){ - return ResultCodeMap.get(rc); - } - - /** - Internal level of indirection required because we cannot initialize - static enum members in an enum before the enum constructor is - invoked. - */ - private static final class ResultCodeMap { - private static final java.util.Map i2e - = new java.util.HashMap<>(); - private static void set(int rc, ResultCode e){ i2e.put(rc, e); } - private static ResultCode get(int rc){ return i2e.get(rc); } - } - -} diff --git a/ext/jni/src/org/sqlite/jni/annotation/Canonical.java b/ext/jni/src/org/sqlite/jni/annotation/Canonical.java deleted file mode 100644 index fdb157335f..0000000000 --- a/ext/jni/src/org/sqlite/jni/annotation/Canonical.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.sqlite.jni.annotation; - -/** - This annotation is for marking functions as "canonical", meaning - that they map directly to a function in the core sqlite3 C API. The - intent is to distinguish them from functions added specifically to - the Java API. - -

Canonical functions, unless specifically documented, have the - same semantics as their counterparts in the C API - documentation, despite their signatures perhaps differing - slightly. Canonical forms may be native or implemented in Java. - Sometimes multiple overloads are labeled as Canonical because one - or more of them are just type- or encoding-related conversion - wrappers but provide identical semantics (e.g. from a String to a - byte[]). The Java API adds a number of convenience overloads to - simplify use, as well as a few Java-specific functions, and those - are never flagged as @Canonical. - -

In some cases, the canonical version of a function is private - and exposed to Java via public overloads. - -

The comment property can be used to add a comment. -*/ -@java.lang.annotation.Documented -@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) -@java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) -public @interface Canonical{ - /** - Brief comments about the binding, e.g. noting any major - semantic differences. - */ - String comment() default ""; -} diff --git a/ext/jni/src/org/sqlite/jni/annotation/NotNull.java b/ext/jni/src/org/sqlite/jni/annotation/NotNull.java index 49003358db..3b4c1c7af1 100644 --- a/ext/jni/src/org/sqlite/jni/annotation/NotNull.java +++ b/ext/jni/src/org/sqlite/jni/annotation/NotNull.java @@ -1,3 +1,16 @@ +/* +** 2023-09-27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file houses the NotNull annotaion for the sqlite3 C API. +*/ package org.sqlite.jni.annotation; /** @@ -20,6 +33,11 @@ package org.sqlite.jni.annotation; any parameter marked with this annoation specifically invokes undefined behavior.

+

Passing 0 (i.e. C NULL) or a negative value for any long-type + parameter marked with this annoation specifically invokes undefined + behavior. Such values are treated as C pointers in the JNI + layer.

+

Note that the C-style API does not throw any exceptions on its own because it has a no-throw policy in order to retain its C-style semantics, but it may trigger NullPointerExceptions (or similar) if @@ -29,10 +47,11 @@ package org.sqlite.jni.annotation; programmatically ensure that NotNull is conformed to in client code.

-

This annotation is solely for the use by the classes in this - package but is made public so that javadoc will link to it from the - annotated functions. It is not part of the public API and - client-level code must not rely on it.

+

This annotation is solely for the use by the classes in the + org.sqlite package and subpackages, but is made public so that + javadoc will link to it from the annotated functions. It is not + part of the public API and client-level code must not rely on + it.

*/ @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) diff --git a/ext/jni/src/org/sqlite/jni/annotation/Nullable.java b/ext/jni/src/org/sqlite/jni/annotation/Nullable.java index 7a011e33b1..ddc8502d67 100644 --- a/ext/jni/src/org/sqlite/jni/annotation/Nullable.java +++ b/ext/jni/src/org/sqlite/jni/annotation/Nullable.java @@ -1,3 +1,16 @@ +/* +** 2023-09-27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file houses the Nullable annotaion for the sqlite3 C API. +*/ package org.sqlite.jni.annotation; /** diff --git a/ext/jni/src/org/sqlite/jni/annotation/package-info.java b/ext/jni/src/org/sqlite/jni/annotation/package-info.java index 50db2a32bd..20ac7a3017 100644 --- a/ext/jni/src/org/sqlite/jni/annotation/package-info.java +++ b/ext/jni/src/org/sqlite/jni/annotation/package-info.java @@ -1,4 +1,17 @@ +/* +** 2023-09-27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ /** - This package houses annotations specific a JNI binding to the SQLite3 C API. + This package houses annotations specific to the JNI bindings of the + SQLite3 C API. */ package org.sqlite.jni.annotation; diff --git a/ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java b/ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java similarity index 97% rename from ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java rename to ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java index 63cac66a52..925536636e 100644 --- a/ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; import org.sqlite.jni.annotation.NotNull; /** diff --git a/ext/jni/src/org/sqlite/jni/AggregateFunction.java b/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java similarity index 98% rename from ext/jni/src/org/sqlite/jni/AggregateFunction.java rename to ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java index 502cde12f8..89c4f27421 100644 --- a/ext/jni/src/org/sqlite/jni/AggregateFunction.java +++ b/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** diff --git a/ext/jni/src/org/sqlite/jni/AuthorizerCallback.java b/ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java similarity index 89% rename from ext/jni/src/org/sqlite/jni/AuthorizerCallback.java rename to ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java index 6dbd9cb77b..ce7c6fca6d 100644 --- a/ext/jni/src/org/sqlite/jni/AuthorizerCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java @@ -11,11 +11,11 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; import org.sqlite.jni.annotation.*; /** - Callback for use with {@link SQLite3Jni#sqlite3_set_authorizer}. + Callback for use with {@link CApi#sqlite3_set_authorizer}. */ public interface AuthorizerCallback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java b/ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java similarity index 92% rename from ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java rename to ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java index 4a36941306..7a54132d29 100644 --- a/ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with the {@link SQLite3Jni#sqlite3_auto_extension} + Callback for use with the {@link CApi#sqlite3_auto_extension} family of APIs. */ public interface AutoExtensionCallback extends CallbackProxy { diff --git a/ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java b/ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java similarity index 88% rename from ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java rename to ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java index 30a5edc037..00223f0b66 100644 --- a/ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with {@link SQLite3Jni#sqlite3_busy_handler}. + Callback for use with {@link CApi#sqlite3_busy_handler}. */ public interface BusyHandlerCallback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/SQLite3Jni.java b/ext/jni/src/org/sqlite/jni/capi/CApi.java similarity index 72% rename from ext/jni/src/org/sqlite/jni/SQLite3Jni.java rename to ext/jni/src/org/sqlite/jni/capi/CApi.java index d6cd5cab53..302cdb760e 100644 --- a/ext/jni/src/org/sqlite/jni/SQLite3Jni.java +++ b/ext/jni/src/org/sqlite/jni/capi/CApi.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file declares JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; import java.nio.charset.StandardCharsets; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -27,11 +27,19 @@ import java.util.Arrays; use, a static import is recommended:
{@code
-  import static org.sqlite.jni.SQLite3Jni.*;
+  import static org.sqlite.jni.capi.CApi.*;
   }

The C-side part can be found in sqlite3-jni.c. +

This class is package-private in order to keep Java clients from + having direct access to the low-level C-style APIs, a design + decision made by Java developers based on the C-style API being + riddled with opportunities for Java developers to proverbially shoot + themselves in the foot with. Third-party copies of this code may + eliminate that guard by simply changing this class from + package-private to public. Its methods which are intended to be + exposed that way are all public.

Only functions which materially differ from their C counterparts are documented here, and only those material differences are @@ -48,12 +56,6 @@ import java.util.Arrays; #sqlite3_result_int}, and sqlite3_result_set() has many type-specific overloads. -

Though most of the {@code SQLITE_abc...} C macros represented by - this class are defined as final, a few are necessarily non-final - because they cannot be set until static class-level initialization - is run. Modifying them at runtime has no effect on the library but - may confuse any client-level code which uses them. -

Notes regarding Java's Modified UTF-8 vs standard UTF-8:

SQLite internally uses UTF-8 encoding, whereas Java natively uses @@ -75,7 +77,7 @@ import java.util.Arrays; Java strings converted to byte arrays for encoding purposes are not NUL-terminated, and conversion to a Java byte array must sometimes be careful to add one. Functions which take a length do not require - this so long as the length is provided. Search the SQLite3Jni class + this so long as the length is provided. Search the CApi class for "\0" for many examples. @@ -89,15 +91,23 @@ import java.util.Arrays;

https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8 */ -public final class SQLite3Jni { +public final class CApi { static { System.loadLibrary("sqlite3-jni"); } //! Not used - private SQLite3Jni(){} + private CApi(){} //! Called from static init code. private static native void init(); + /** + Returns a nul-terminated copy of s as a UTF-8-encoded byte array, + or null if s is null. + */ + private static byte[] nulTerminateUtf8(String s){ + return null==s ? null : (s+"\0").getBytes(StandardCharsets.UTF_8); + } + /** Each thread which uses the SQLite3 JNI APIs should call sqlite3_jni_uncache_thread() when it is done with the library - @@ -118,8 +128,7 @@ public final class SQLite3Jni {

This routine returns false without side effects if the current JNIEnv is not cached, else returns true, but this information is primarily for testing of the JNI bindings and is not information - which client-level code should use to make any informed - decisions. + which client-level code can use to make any informed decisions. */ public static native boolean sqlite3_java_uncache_thread(); @@ -144,97 +153,140 @@ public final class SQLite3Jni { allocation error. In all casses, 0 is considered the sentinel "not a key" value. */ - @Canonical public static native long sqlite3_aggregate_context(sqlite3_context cx, boolean initialize); /** Functions almost as documented for the C API, with these exceptions: -

- The callback interface is is shorter because of +

- The callback interface is shorter because of cross-language differences. Specifically, 3rd argument to the C auto-extension callback interface is unnecessary here. -

The C API docs do not specifically say so, but if the list of auto-extensions is manipulated from an auto-extension, it is undefined which, if any, auto-extensions will subsequently - execute for the current database. + execute for the current database. That is, doing so will result + in unpredictable, but not undefined, behavior.

See the AutoExtension class docs for more information. */ - @Canonical public static native int sqlite3_auto_extension(@NotNull AutoExtensionCallback callback); - @Canonical - public static native int sqlite3_backup_finish(@NotNull sqlite3_backup b); + static native int sqlite3_backup_finish(@NotNull long ptrToBackup); - @Canonical - public static native sqlite3_backup sqlite3_backup_init( - @NotNull sqlite3 dbDest, @NotNull String destTableName, - @NotNull sqlite3 dbSrc, @NotNull String srcTableName + public static int sqlite3_backup_finish(@NotNull sqlite3_backup b){ + return sqlite3_backup_finish(b.clearNativePointer()); + } + + static native sqlite3_backup sqlite3_backup_init( + @NotNull long ptrToDbDest, @NotNull String destTableName, + @NotNull long ptrToDbSrc, @NotNull String srcTableName ); - @Canonical - public static native int sqlite3_backup_pagecount(@NotNull sqlite3_backup b); + public static sqlite3_backup sqlite3_backup_init( + @NotNull sqlite3 dbDest, @NotNull String destTableName, + @NotNull sqlite3 dbSrc, @NotNull String srcTableName + ){ + return sqlite3_backup_init( dbDest.getNativePointer(), destTableName, + dbSrc.getNativePointer(), srcTableName ); + } - @Canonical - public static native int sqlite3_backup_remaining(@NotNull sqlite3_backup b); + static native int sqlite3_backup_pagecount(@NotNull long ptrToBackup); - @Canonical - public static native int sqlite3_backup_step( - @NotNull sqlite3_backup b, int nPage + public static int sqlite3_backup_pagecount(@NotNull sqlite3_backup b){ + return sqlite3_backup_pagecount(b.getNativePointer()); + } + + static native int sqlite3_backup_remaining(@NotNull long ptrToBackup); + + public static int sqlite3_backup_remaining(@NotNull sqlite3_backup b){ + return sqlite3_backup_remaining(b.getNativePointer()); + } + + static native int sqlite3_backup_step(@NotNull long ptrToBackup, int nPage); + + public static int sqlite3_backup_step(@NotNull sqlite3_backup b, int nPage){ + return sqlite3_backup_step(b.getNativePointer(), nPage); + } + + static native int sqlite3_bind_blob( + @NotNull long ptrToStmt, int ndx, @Nullable byte[] data, int n ); /** - Results are undefined if data is not null and n<0 || n>=data.length. + If n is negative, SQLITE_MISUSE is returned. If n>data.length + then n is silently truncated to data.length. */ - @Canonical - public static native int sqlite3_bind_blob( + static int sqlite3_bind_blob( @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] data, int n - ); + ){ + return sqlite3_bind_blob(stmt.getNativePointer(), ndx, data, n); + } public static int sqlite3_bind_blob( @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] data ){ return (null==data) - ? sqlite3_bind_null(stmt, ndx) - : sqlite3_bind_blob(stmt, ndx, data, data.length); + ? sqlite3_bind_null(stmt.getNativePointer(), ndx) + : sqlite3_bind_blob(stmt.getNativePointer(), ndx, data, data.length); } - @Canonical - public static native int sqlite3_bind_double( + static native int sqlite3_bind_double( + @NotNull long ptrToStmt, int ndx, double v + ); + + public static int sqlite3_bind_double( @NotNull sqlite3_stmt stmt, int ndx, double v + ){ + return sqlite3_bind_double(stmt.getNativePointer(), ndx, v); + } + + static native int sqlite3_bind_int( + @NotNull long ptrToStmt, int ndx, int v ); - @Canonical - public static native int sqlite3_bind_int( + public static int sqlite3_bind_int( @NotNull sqlite3_stmt stmt, int ndx, int v + ){ + return sqlite3_bind_int(stmt.getNativePointer(), ndx, v); + } + + static native int sqlite3_bind_int64( + @NotNull long ptrToStmt, int ndx, long v ); - @Canonical - public static native int sqlite3_bind_int64( - @NotNull sqlite3_stmt stmt, int ndx, long v + public static int sqlite3_bind_int64(@NotNull sqlite3_stmt stmt, int ndx, long v){ + return sqlite3_bind_int64( stmt.getNativePointer(), ndx, v ); + } + + static native int sqlite3_bind_java_object( + @NotNull long ptrToStmt, int ndx, @Nullable Object o ); /** - Binds the given object at the given index. + Binds the given object at the given index. If o is null then this behaves like + sqlite3_bind_null(). @see #sqlite3_result_java_object */ - public static native int sqlite3_bind_java_object( - @NotNull sqlite3_stmt cx, int ndx, @Nullable Object o - ); + public static int sqlite3_bind_java_object( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable Object o + ){ + return sqlite3_bind_java_object(stmt.getNativePointer(), ndx, o); + } - @Canonical - public static native int sqlite3_bind_null( - @NotNull sqlite3_stmt stmt, int ndx - ); + static native int sqlite3_bind_null(@NotNull long ptrToStmt, int ndx); - @Canonical - public static native int sqlite3_bind_parameter_count( - @NotNull sqlite3_stmt stmt - ); + public static int sqlite3_bind_null(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_bind_null(stmt.getNativePointer(), ndx); + } + + static native int sqlite3_bind_parameter_count(@NotNull long ptrToStmt); + + public static int sqlite3_bind_parameter_count(@NotNull sqlite3_stmt stmt){ + return sqlite3_bind_parameter_count(stmt.getNativePointer()); + } /** Requires that paramName be a NUL-terminated UTF-8 string. @@ -246,22 +298,27 @@ public final class SQLite3Jni { overload than to do that in C, so that signature is the public-facing one. */ - @Canonical private static native int sqlite3_bind_parameter_index( - @NotNull sqlite3_stmt stmt, @NotNull byte[] paramName + @NotNull long ptrToStmt, @NotNull byte[] paramName ); - @Canonical public static int sqlite3_bind_parameter_index( @NotNull sqlite3_stmt stmt, @NotNull String paramName ){ - final byte[] utf8 = (paramName+"\0").getBytes(StandardCharsets.UTF_8); - return sqlite3_bind_parameter_index(stmt, utf8); + final byte[] utf8 = nulTerminateUtf8(paramName); + return null==utf8 ? 0 : sqlite3_bind_parameter_index(stmt.getNativePointer(), utf8); } - @Canonical - public static native String sqlite3_bind_parameter_name( - @NotNull sqlite3_stmt stmt, int index + static native String sqlite3_bind_parameter_name( + @NotNull long ptrToStmt, int index + ); + + public static String sqlite3_bind_parameter_name(@NotNull sqlite3_stmt stmt, int index){ + return sqlite3_bind_parameter_name(stmt.getNativePointer(), index); + } + + static native int sqlite3_bind_text( + @NotNull long ptrToStmt, int ndx, @Nullable byte[] utf8, int maxBytes ); /** @@ -269,14 +326,16 @@ public final class SQLite3Jni { SQLITE_TRANSIENT for the final C API parameter. The byte array is assumed to be in UTF-8 encoding. -

Results are undefined if data is not null and - maxBytes>=utf8.length. If maxBytes is negative then results are - undefined if data is not null and does not contain a NUL byte. +

If data is not null and maxBytes>utf8.length then maxBytes is + silently truncated to utf8.length. If maxBytes is negative then + results are undefined if data is not null and does not contain a + NUL byte. */ - @Canonical - public static native int sqlite3_bind_text( + static int sqlite3_bind_text( @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] utf8, int maxBytes - ); + ){ + return sqlite3_bind_text(stmt.getNativePointer(), ndx, utf8, maxBytes); + } /** Converts data, if not null, to a UTF-8-encoded byte array and @@ -286,9 +345,9 @@ public final class SQLite3Jni { public static int sqlite3_bind_text( @NotNull sqlite3_stmt stmt, int ndx, @Nullable String data ){ - if(null == data) return sqlite3_bind_null(stmt, ndx); + if( null==data ) return sqlite3_bind_null(stmt.getNativePointer(), ndx); final byte[] utf8 = data.getBytes(StandardCharsets.UTF_8); - return sqlite3_bind_text(stmt, ndx, utf8, utf8.length); + return sqlite3_bind_text(stmt.getNativePointer(), ndx, utf8, utf8.length); } /** @@ -297,20 +356,25 @@ public final class SQLite3Jni { public static int sqlite3_bind_text( @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] utf8 ){ - return (null == utf8) - ? sqlite3_bind_null(stmt, ndx) - : sqlite3_bind_text(stmt, ndx, utf8, utf8.length); + return ( null==utf8 ) + ? sqlite3_bind_null(stmt.getNativePointer(), ndx) + : sqlite3_bind_text(stmt.getNativePointer(), ndx, utf8, utf8.length); } + static native int sqlite3_bind_text16( + @NotNull long ptrToStmt, int ndx, @Nullable byte[] data, int maxBytes + ); + /** Identical to the sqlite3_bind_text() overload with the same signature but requires that its input be encoded in UTF-16 in platform byte order. */ - @Canonical - public static native int sqlite3_bind_text16( + static int sqlite3_bind_text16( @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] data, int maxBytes - ); + ){ + return sqlite3_bind_text16(stmt.getNativePointer(), ndx, data, maxBytes); + } /** Converts its string argument to UTF-16 and binds it as such, returning @@ -322,7 +386,7 @@ public final class SQLite3Jni { ){ if(null == data) return sqlite3_bind_null(stmt, ndx); final byte[] bytes = data.getBytes(StandardCharsets.UTF_16); - return sqlite3_bind_text16(stmt, ndx, bytes, bytes.length); + return sqlite3_bind_text16(stmt.getNativePointer(), ndx, bytes, bytes.length); } /** @@ -334,33 +398,62 @@ public final class SQLite3Jni { @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] data ){ return (null == data) - ? sqlite3_bind_null(stmt, ndx) - : sqlite3_bind_text16(stmt, ndx, data, data.length); + ? sqlite3_bind_null(stmt.getNativePointer(), ndx) + : sqlite3_bind_text16(stmt.getNativePointer(), ndx, data, data.length); } - @Canonical - public static native int sqlite3_bind_zeroblob( - @NotNull sqlite3_stmt stmt, int ndx, int n + static native int sqlite3_bind_value(@NotNull long ptrToStmt, int ndx, long ptrToValue); + + /** + Functions like the C-level sqlite3_bind_value(), or + sqlite3_bind_null() if val is null. + */ + public static int sqlite3_bind_value(@NotNull sqlite3_stmt stmt, int ndx, sqlite3_value val){ + return sqlite3_bind_value(stmt.getNativePointer(), ndx, + null==val ? 0L : val.getNativePointer()); + } + + static native int sqlite3_bind_zeroblob(@NotNull long ptrToStmt, int ndx, int n); + + public static int sqlite3_bind_zeroblob(@NotNull sqlite3_stmt stmt, int ndx, int n){ + return sqlite3_bind_zeroblob(stmt.getNativePointer(), ndx, n); + } + + static native int sqlite3_bind_zeroblob64( + @NotNull long ptrToStmt, int ndx, long n ); - @Canonical - public static native int sqlite3_bind_zeroblob64( - @NotNull sqlite3_stmt stmt, int ndx, long n - ); + public static int sqlite3_bind_zeroblob64(@NotNull sqlite3_stmt stmt, int ndx, long n){ + return sqlite3_bind_zeroblob64(stmt.getNativePointer(), ndx, n); + } - @Canonical - public static native int sqlite3_blob_bytes(@NotNull sqlite3_blob blob); + static native int sqlite3_blob_bytes(@NotNull long ptrToBlob); - @Canonical - public static native int sqlite3_blob_close(@Nullable sqlite3_blob blob); + public static int sqlite3_blob_bytes(@NotNull sqlite3_blob blob){ + return sqlite3_blob_bytes(blob.getNativePointer()); + } - @Canonical - public static native int sqlite3_blob_open( - @NotNull sqlite3 db, @NotNull String dbName, + static native int sqlite3_blob_close(@Nullable long ptrToBlob); + + public static int sqlite3_blob_close(@Nullable sqlite3_blob blob){ + return sqlite3_blob_close(blob.clearNativePointer()); + } + + static native int sqlite3_blob_open( + @NotNull long ptrToDb, @NotNull String dbName, @NotNull String tableName, @NotNull String columnName, long iRow, int flags, @NotNull OutputPointer.sqlite3_blob out ); + public static int sqlite3_blob_open( + @NotNull sqlite3 db, @NotNull String dbName, + @NotNull String tableName, @NotNull String columnName, + long iRow, int flags, @NotNull OutputPointer.sqlite3_blob out + ){ + return sqlite3_blob_open(db.getNativePointer(), dbName, tableName, + columnName, iRow, flags, out); + } + /** Convenience overload. */ @@ -369,23 +462,41 @@ public final class SQLite3Jni { @NotNull String tableName, @NotNull String columnName, long iRow, int flags ){ final OutputPointer.sqlite3_blob out = new OutputPointer.sqlite3_blob(); - sqlite3_blob_open(db, dbName, tableName, columnName, iRow, flags, out); + sqlite3_blob_open(db.getNativePointer(), dbName, tableName, columnName, + iRow, flags, out); return out.take(); }; - @Canonical - public static native int sqlite3_blob_read( + static native int sqlite3_blob_read( + @NotNull long ptrToBlob, @NotNull byte[] target, int iOffset + ); + + public static int sqlite3_blob_read( @NotNull sqlite3_blob b, @NotNull byte[] target, int iOffset + ){ + return sqlite3_blob_read(b.getNativePointer(), target, iOffset); + } + + static native int sqlite3_blob_reopen( + @NotNull long ptrToBlob, long newRowId ); - @Canonical - public static native int sqlite3_blob_reopen( - @NotNull sqlite3_blob out, long newRowId + public static int sqlite3_blob_reopen(@NotNull sqlite3_blob b, long newRowId){ + return sqlite3_blob_reopen(b.getNativePointer(), newRowId); + } + + static native int sqlite3_blob_write( + @NotNull long ptrToBlob, @NotNull byte[] bytes, int iOffset ); - @Canonical - public static native int sqlite3_blob_write( - @NotNull sqlite3_blob out, @NotNull byte[] bytes, int iOffset + public static int sqlite3_blob_write( + @NotNull sqlite3_blob b, @NotNull byte[] bytes, int iOffset + ){ + return sqlite3_blob_write(b.getNativePointer(), bytes, iOffset); + } + + static native int sqlite3_busy_handler( + @NotNull long ptrToDb, @Nullable BusyHandlerCallback handler ); /** @@ -393,100 +504,120 @@ public final class SQLite3Jni { BusyHandlerCallback instance in place of a callback function. Pass it a null handler to clear the busy handler. */ - @Canonical - public static native int sqlite3_busy_handler( + public static int sqlite3_busy_handler( @NotNull sqlite3 db, @Nullable BusyHandlerCallback handler - ); + ){ + return sqlite3_busy_handler(db.getNativePointer(), handler); + } - @Canonical - public static native int sqlite3_busy_timeout( - @NotNull sqlite3 db, int ms - ); + static native int sqlite3_busy_timeout(@NotNull long ptrToDb, int ms); + + public static int sqlite3_busy_timeout(@NotNull sqlite3 db, int ms){ + return sqlite3_busy_timeout(db.getNativePointer(), ms); + } - @Canonical public static native boolean sqlite3_cancel_auto_extension( @NotNull AutoExtensionCallback ax ); - @Canonical - public static native int sqlite3_changes( - @NotNull sqlite3 db - ); + static native int sqlite3_changes(@NotNull long ptrToDb); - @Canonical - public static native long sqlite3_changes64( - @NotNull sqlite3 db - ); + public static int sqlite3_changes(@NotNull sqlite3 db){ + return sqlite3_changes(db.getNativePointer()); + } - @Canonical - public static native int sqlite3_clear_bindings( - @NotNull sqlite3_stmt stmt - ); + static native long sqlite3_changes64(@NotNull long ptrToDb); - @Canonical - public static native int sqlite3_close( - @Nullable sqlite3 db - ); + public static long sqlite3_changes64(@NotNull sqlite3 db){ + return sqlite3_changes64(db.getNativePointer()); + } - @Canonical - public static native int sqlite3_close_v2( - @Nullable sqlite3 db - ); + static native int sqlite3_clear_bindings(@NotNull long ptrToStmt); + + public static int sqlite3_clear_bindings(@NotNull sqlite3_stmt stmt){ + return sqlite3_clear_bindings(stmt.getNativePointer()); + } + + static native int sqlite3_close(@Nullable long ptrToDb); + + public static int sqlite3_close(@Nullable sqlite3 db){ + int rc = 0; + if( null!=db ){ + rc = sqlite3_close(db.getNativePointer()); + if( 0==rc ) db.clearNativePointer(); + } + return rc; + } + + static native int sqlite3_close_v2(@Nullable long ptrToDb); + + public static int sqlite3_close_v2(@Nullable sqlite3 db){ + return db==null ? 0 : sqlite3_close_v2(db.clearNativePointer()); + } - @Canonical public static native byte[] sqlite3_column_blob( @NotNull sqlite3_stmt stmt, int ndx ); - @Canonical - public static native int sqlite3_column_bytes( - @NotNull sqlite3_stmt stmt, int ndx - ); + static native int sqlite3_column_bytes(@NotNull long ptrToStmt, int ndx); - @Canonical - public static native int sqlite3_column_bytes16( - @NotNull sqlite3_stmt stmt, int ndx - ); + public static int sqlite3_column_bytes(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_bytes(stmt.getNativePointer(), ndx); + } - @Canonical - public static native int sqlite3_column_count( - @NotNull sqlite3_stmt stmt - ); + static native int sqlite3_column_bytes16(@NotNull long ptrToStmt, int ndx); + + public static int sqlite3_column_bytes16(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_bytes16(stmt.getNativePointer(), ndx); + } + + static native int sqlite3_column_count(@NotNull long ptrToStmt); + + public static int sqlite3_column_count(@NotNull sqlite3_stmt stmt){ + return sqlite3_column_count(stmt.getNativePointer()); + } + + static native String sqlite3_column_decltype(@NotNull long ptrToStmt, int ndx); + + public static String sqlite3_column_decltype(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_decltype(stmt.getNativePointer(), ndx); + } - @Canonical public static native double sqlite3_column_double( @NotNull sqlite3_stmt stmt, int ndx ); - @Canonical public static native int sqlite3_column_int( @NotNull sqlite3_stmt stmt, int ndx ); - @Canonical public static native long sqlite3_column_int64( @NotNull sqlite3_stmt stmt, int ndx ); - @Canonical - public static native String sqlite3_column_name( - @NotNull sqlite3_stmt stmt, int ndx - ); + static native String sqlite3_column_name(@NotNull long ptrToStmt, int ndx); - @Canonical - public static native String sqlite3_column_database_name( - @NotNull sqlite3_stmt stmt, int ndx - ); + public static String sqlite3_column_name(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_name(stmt.getNativePointer(), ndx); + } - @Canonical - public static native String sqlite3_column_origin_name( - @NotNull sqlite3_stmt stmt, int ndx - ); + static native String sqlite3_column_database_name(@NotNull long ptrToStmt, int ndx); - @Canonical - public static native String sqlite3_column_table_name( - @NotNull sqlite3_stmt stmt, int ndx - ); + public static String sqlite3_column_database_name(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_database_name(stmt.getNativePointer(), ndx); + } + + static native String sqlite3_column_origin_name(@NotNull long ptrToStmt, int ndx); + + public static String sqlite3_column_origin_name(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_origin_name(stmt.getNativePointer(), ndx); + } + + static native String sqlite3_column_table_name(@NotNull long ptrToStmt, int ndx); + + public static String sqlite3_column_table_name(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_table_name(stmt.getNativePointer(), ndx); + } /** Functions identially to the C API, and this note is just to @@ -496,12 +627,10 @@ public final class SQLite3Jni { @see #sqlite3_column_text16(sqlite3_stmt,int) */ - @Canonical public static native byte[] sqlite3_column_text( @NotNull sqlite3_stmt stmt, int ndx ); - @Canonical public static native String sqlite3_column_text16( @NotNull sqlite3_stmt stmt, int ndx ); @@ -543,55 +672,58 @@ public final class SQLite3Jni { // return rv; // } - @Canonical - public static native int sqlite3_column_type( + static native int sqlite3_column_type(@NotNull long ptrToStmt, int ndx); + + public static int sqlite3_column_type(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_type(stmt.getNativePointer(), ndx); + } + + public static native sqlite3_value sqlite3_column_value( @NotNull sqlite3_stmt stmt, int ndx ); - @Canonical - public static native sqlite3_value sqlite3_column_value( - @NotNull sqlite3_stmt stmt, int ndx + static native int sqlite3_collation_needed( + @NotNull long ptrToDb, @Nullable CollationNeededCallback callback ); /** This functions like C's sqlite3_collation_needed16() because Java's string type is inherently compatible with that interface. */ - @Canonical - public static native int sqlite3_collation_needed( + public static int sqlite3_collation_needed( @NotNull sqlite3 db, @Nullable CollationNeededCallback callback + ){ + return sqlite3_collation_needed(db.getNativePointer(), callback); + } + + static native CommitHookCallback sqlite3_commit_hook( + @NotNull long ptrToDb, @Nullable CommitHookCallback hook ); - @Canonical - public static native CommitHookCallback sqlite3_commit_hook( + public static CommitHookCallback sqlite3_commit_hook( @NotNull sqlite3 db, @Nullable CommitHookCallback hook - ); + ){ + return sqlite3_commit_hook(db.getNativePointer(), hook); + } - @Canonical - public static native String sqlite3_compileoption_get( - int n - ); + public static native String sqlite3_compileoption_get(int n); - @Canonical - public static native boolean sqlite3_compileoption_used( - @NotNull String optName - ); + public static native boolean sqlite3_compileoption_used(String optName); /** This implementation is private because it's too easy to pass it - non-NUL-terminated arrays. + non-NUL-terminated byte arrays from client code. */ - @Canonical private static native int sqlite3_complete( @NotNull byte[] nulTerminatedUtf8Sql ); - @Canonical() + /** + Unlike the C API, this returns SQLITE_MISUSE if its argument is + null (as opposed to invoking UB). + */ public static int sqlite3_complete(@NotNull String sql){ - /* Design note: we don't implement this in native code because we - won't get a NUL-terminated string there unless we make our own - copy to add a terminator. That's much easier to do here. */ - return sqlite3_complete( (sql+"\0").getBytes(StandardCharsets.UTF_8) ); + return sqlite3_complete( nulTerminateUtf8(sql) ); } @@ -610,9 +742,6 @@ public final class SQLite3Jni { the rest of the library. This must not be called when any other library APIs are being called. */ - @Canonical(comment="Option subset: "+ - "SQLITE_CONFIG_SINGLETHREAD, SQLITE_CONFIG_MULTITHREAD, "+ - "SQLITE_CONFIG_SERIALIZED") public static native int sqlite3_config(int op); /** @@ -629,22 +758,22 @@ public final class SQLite3Jni { the rest of the library. This must not be called when any other library APIs are being called. */ - @Canonical(comment="Option subset: SQLITE_CONFIG_SQLLOG") public static native int sqlite3_config( @Nullable ConfigSqllogCallback logger ); /** The sqlite3_config() overload for handling the SQLITE_CONFIG_LOG option. */ - @Canonical(comment="Option subset: SQLITE_CONFIG_LOG") public static native int sqlite3_config( @Nullable ConfigLogCallback logger ); - @Canonical + /** + Unlike the C API, this returns null if its argument is + null (as opposed to invoking UB). + */ public static native sqlite3 sqlite3_context_db_handle( @NotNull sqlite3_context cx ); - @Canonical public static native int sqlite3_create_collation( @NotNull sqlite3 db, @NotNull String name, int eTextRep, @NotNull CollationCallback col @@ -657,24 +786,29 @@ public final class SQLite3Jni { depends on which methods the final argument implements. See SQLFunction's subclasses (ScalarFunction, AggregateFunction, and WindowFunction) for details. + +

Unlike the C API, this returns SQLITE_MISUSE null if its db or + functionName arguments are null (as opposed to invoking UB). */ - @Canonical public static native int sqlite3_create_function( @NotNull sqlite3 db, @NotNull String functionName, int nArg, int eTextRep, @NotNull SQLFunction func ); - @Canonical - public static native int sqlite3_data_count( - @NotNull sqlite3_stmt stmt - ); + static native int sqlite3_data_count(@NotNull long ptrToStmt); + + public static int sqlite3_data_count(@NotNull sqlite3_stmt stmt){ + return sqlite3_data_count(stmt.getNativePointer()); + } /** Overload for sqlite3_db_config() calls which take (int,int*) variadic arguments. Returns SQLITE_MISUSE if op is not one of the SQLITE_DBCONFIG_... options which uses this call form. + +

Unlike the C API, this returns SQLITE_MISUSE if its db argument + are null (as opposed to invoking UB). */ - @Canonical public static native int sqlite3_db_config( @NotNull sqlite3 db, int op, int onOff, @Nullable OutputPointer.Int32 out ); @@ -686,97 +820,103 @@ public final class SQLite3Jni { SQLITE_DBCONFIG_MAINDBNAME, but that set of options may be extended in future versions. */ - @Canonical(comment="Supports only a subset of options.") public static native int sqlite3_db_config( @NotNull sqlite3 db, int op, @NotNull String val ); - @Canonical + private static native String sqlite3_db_name(@NotNull long ptrToDb, int ndx); + + public static String sqlite3_db_name(@NotNull sqlite3 db, int ndx){ + return null==db ? null : sqlite3_db_name(db.getNativePointer(), ndx); + } + + public static native String sqlite3_db_filename( @NotNull sqlite3 db, @NotNull String dbName ); - @Canonical - public static native sqlite3 sqlite3_db_handle( @NotNull sqlite3_stmt stmt ); + public static native sqlite3 sqlite3_db_handle(@NotNull sqlite3_stmt stmt); + + public static native int sqlite3_db_readonly(@NotNull sqlite3 db, String dbName); - @Canonical public static native int sqlite3_db_release_memory(sqlite3 db); - @Canonical public static native int sqlite3_db_status( @NotNull sqlite3 db, int op, @NotNull OutputPointer.Int32 pCurrent, @NotNull OutputPointer.Int32 pHighwater, boolean reset ); - @Canonical public static native int sqlite3_errcode(@NotNull sqlite3 db); - @Canonical - public static native String sqlite3_errmsg16(@NotNull sqlite3 db); + public static native String sqlite3_errmsg(@NotNull sqlite3 db); - @Canonical - public static native String sqlite3_errstr(int resultCode); - - @Canonical - public static native String sqlite3_expanded_sql(@NotNull sqlite3_stmt stmt); - - @Canonical - public static native int sqlite3_extended_errcode(@NotNull sqlite3 db); - - @Canonical - public static native boolean sqlite3_extended_result_codes( - @NotNull sqlite3 db, boolean onoff - ); - - @Canonical - public static native boolean sqlite3_get_autocommit(@NotNull sqlite3 db); - - @Canonical - public static native Object sqlite3_get_auxdata( - @NotNull sqlite3_context cx, int n - ); + static native int sqlite3_error_offset(@NotNull long ptrToDb); /** Note that the returned byte offset values assume UTF-8-encoded inputs, so won't always match character offsets in Java Strings. */ - @Canonical - public static native int sqlite3_error_offset(@NotNull sqlite3 db); + public static int sqlite3_error_offset(@NotNull sqlite3 db){ + return sqlite3_error_offset(db.getNativePointer()); + } - @Canonical - public static native int sqlite3_finalize(@NotNull sqlite3_stmt stmt); + public static native String sqlite3_errstr(int resultCode); + + public static native String sqlite3_expanded_sql(@NotNull sqlite3_stmt stmt); + + static native int sqlite3_extended_errcode(@NotNull long ptrToDb); + + public static int sqlite3_extended_errcode(@NotNull sqlite3 db){ + return sqlite3_extended_errcode(db.getNativePointer()); + } + + public static native boolean sqlite3_extended_result_codes( + @NotNull sqlite3 db, boolean onoff + ); + + static native boolean sqlite3_get_autocommit(@NotNull long ptrToDb); + + public static boolean sqlite3_get_autocommit(@NotNull sqlite3 db){ + return sqlite3_get_autocommit(db.getNativePointer()); + } + + public static native Object sqlite3_get_auxdata( + @NotNull sqlite3_context cx, int n + ); + + static native int sqlite3_finalize(long ptrToStmt); + + public static int sqlite3_finalize(@NotNull sqlite3_stmt stmt){ + return null==stmt ? 0 : sqlite3_finalize(stmt.clearNativePointer()); + } - @Canonical public static native int sqlite3_initialize(); - @Canonical public static native void sqlite3_interrupt(@NotNull sqlite3 db); - @Canonical public static native boolean sqlite3_is_interrupted(@NotNull sqlite3 db); - @Canonical public static native boolean sqlite3_keyword_check(@NotNull String word); - @Canonical public static native int sqlite3_keyword_count(); - @Canonical public static native String sqlite3_keyword_name(int index); - @Canonical public static native long sqlite3_last_insert_rowid(@NotNull sqlite3 db); - @Canonical public static native String sqlite3_libversion(); - @Canonical public static native int sqlite3_libversion_number(); - @Canonical public static native int sqlite3_limit(@NotNull sqlite3 db, int id, int newVal); + /** + Only available if built with SQLITE_ENABLE_NORMALIZE. If not, it always + returns null. + */ + public static native String sqlite3_normalized_sql(@NotNull sqlite3_stmt stmt); + /** Works like its C counterpart and makes the native pointer of the underling (sqlite3*) object available via @@ -790,7 +930,6 @@ public final class SQLite3Jni { object and it is up to the caller to sqlite3_close() that db handle. */ - @Canonical public static native int sqlite3_open( @Nullable String filename, @NotNull OutputPointer.sqlite3 ppDb ); @@ -809,7 +948,6 @@ public final class SQLite3Jni { return out.take(); }; - @Canonical public static native int sqlite3_open_v2( @Nullable String filename, @NotNull OutputPointer.sqlite3 ppDb, int flags, @Nullable String zVfs @@ -846,7 +984,7 @@ public final class SQLite3Jni { necessary, however, and overloads are provided which gloss over that. -

Results are undefined if maxBytes>=sqlUtf8.length. +

Results are undefined if maxBytes>sqlUtf8.length.

This routine is private because its maxBytes value is not strictly necessary in the Java interface, as sqlUtf8.length tells @@ -854,9 +992,8 @@ public final class SQLite3Jni { more ways to shoot themselves in the foot without providing any real utility. */ - @Canonical private static native int sqlite3_prepare( - @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int maxBytes, + @NotNull long ptrToDb, @NotNull byte[] sqlUtf8, int maxBytes, @NotNull OutputPointer.sqlite3_stmt outStmt, @Nullable OutputPointer.Int32 pTailOffset ); @@ -869,20 +1006,21 @@ public final class SQLite3Jni {

Several overloads provided simplified call signatures. */ - @Canonical public static int sqlite3_prepare( @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, @NotNull OutputPointer.sqlite3_stmt outStmt, @Nullable OutputPointer.Int32 pTailOffset ){ - return sqlite3_prepare(db, sqlUtf8, sqlUtf8.length, outStmt, pTailOffset); + return sqlite3_prepare(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + outStmt, pTailOffset); } public static int sqlite3_prepare( @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, @NotNull OutputPointer.sqlite3_stmt outStmt ){ - return sqlite3_prepare(db, sqlUtf8, sqlUtf8.length, outStmt, null); + return sqlite3_prepare(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + outStmt, null); } public static int sqlite3_prepare( @@ -890,7 +1028,8 @@ public final class SQLite3Jni { @NotNull OutputPointer.sqlite3_stmt outStmt ){ final byte[] utf8 = sql.getBytes(StandardCharsets.UTF_8); - return sqlite3_prepare(db, utf8, utf8.length, outStmt, null); + return sqlite3_prepare(db.getNativePointer(), utf8, utf8.length, + outStmt, null); } /** @@ -911,9 +1050,8 @@ public final class SQLite3Jni { /** @see #sqlite3_prepare */ - @Canonical private static native int sqlite3_prepare_v2( - @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int maxBytes, + @NotNull long ptrToDb, @NotNull byte[] sqlUtf8, int maxBytes, @NotNull OutputPointer.sqlite3_stmt outStmt, @Nullable OutputPointer.Int32 pTailOffset ); @@ -923,20 +1061,21 @@ public final class SQLite3Jni { output paramter is returned as the index offset into the given byte array at which SQL parsing stopped. */ - @Canonical public static int sqlite3_prepare_v2( @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, @NotNull OutputPointer.sqlite3_stmt outStmt, @Nullable OutputPointer.Int32 pTailOffset ){ - return sqlite3_prepare_v2(db, sqlUtf8, sqlUtf8.length, outStmt, pTailOffset); + return sqlite3_prepare_v2(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + outStmt, pTailOffset); } public static int sqlite3_prepare_v2( @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, @NotNull OutputPointer.sqlite3_stmt outStmt ){ - return sqlite3_prepare_v2(db, sqlUtf8, sqlUtf8.length, outStmt, null); + return sqlite3_prepare_v2(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + outStmt, null); } public static int sqlite3_prepare_v2( @@ -944,7 +1083,8 @@ public final class SQLite3Jni { @NotNull OutputPointer.sqlite3_stmt outStmt ){ final byte[] utf8 = sql.getBytes(StandardCharsets.UTF_8); - return sqlite3_prepare_v2(db, utf8, utf8.length, outStmt, null); + return sqlite3_prepare_v2(db.getNativePointer(), utf8, utf8.length, + outStmt, null); } /** @@ -962,9 +1102,8 @@ public final class SQLite3Jni { /** @see #sqlite3_prepare */ - @Canonical private static native int sqlite3_prepare_v3( - @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int maxBytes, + @NotNull long ptrToDb, @NotNull byte[] sqlUtf8, int maxBytes, int prepFlags, @NotNull OutputPointer.sqlite3_stmt outStmt, @Nullable OutputPointer.Int32 pTailOffset ); @@ -974,13 +1113,13 @@ public final class SQLite3Jni { output paramter is returned as the index offset into the given byte array at which SQL parsing stopped. */ - @Canonical public static int sqlite3_prepare_v3( @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int prepFlags, @NotNull OutputPointer.sqlite3_stmt outStmt, @Nullable OutputPointer.Int32 pTailOffset ){ - return sqlite3_prepare_v3(db, sqlUtf8, sqlUtf8.length, prepFlags, outStmt, pTailOffset); + return sqlite3_prepare_v3(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + prepFlags, outStmt, pTailOffset); } /** @@ -991,7 +1130,8 @@ public final class SQLite3Jni { @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int prepFlags, @NotNull OutputPointer.sqlite3_stmt outStmt ){ - return sqlite3_prepare_v3(db, sqlUtf8, sqlUtf8.length, prepFlags, outStmt, null); + return sqlite3_prepare_v3(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + prepFlags, outStmt, null); } /** @@ -1004,7 +1144,8 @@ public final class SQLite3Jni { @NotNull OutputPointer.sqlite3_stmt outStmt ){ final byte[] utf8 = sql.getBytes(StandardCharsets.UTF_8); - return sqlite3_prepare_v3(db, utf8, utf8.length, prepFlags, outStmt, null); + return sqlite3_prepare_v3(db.getNativePointer(), utf8, utf8.length, + prepFlags, outStmt, null); } /** @@ -1115,47 +1256,66 @@ public final class SQLite3Jni { return sqlite3_prepare_multi(db, sql, 0, p); } + static native int sqlite3_preupdate_blobwrite(@NotNull long ptrToDb); /** If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this acts as a proxy for C's sqlite3_preupdate_blobwrite(), else it returns SQLITE_MISUSE with no side effects. */ - @Canonical - public static native int sqlite3_preupdate_blobwrite(@NotNull sqlite3 db); + public static int sqlite3_preupdate_blobwrite(@NotNull sqlite3 db){ + return sqlite3_preupdate_blobwrite(db.getNativePointer()); + } + + static native int sqlite3_preupdate_count(@NotNull long ptrToDb); + /** If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this acts as a proxy for C's sqlite3_preupdate_count(), else it returns SQLITE_MISUSE with no side effects. */ - @Canonical - public static native int sqlite3_preupdate_count(@NotNull sqlite3 db); + public static int sqlite3_preupdate_count(@NotNull sqlite3 db){ + return sqlite3_preupdate_count(db.getNativePointer()); + } + + static native int sqlite3_preupdate_depth(@NotNull long ptrToDb); + /** If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this acts as a proxy for C's sqlite3_preupdate_depth(), else it returns SQLITE_MISUSE with no side effects. */ - @Canonical - public static native int sqlite3_preupdate_depth(@NotNull sqlite3 db); + public static int sqlite3_preupdate_depth(@NotNull sqlite3 db){ + return sqlite3_preupdate_depth(db.getNativePointer()); + } + + static native PreupdateHookCallback sqlite3_preupdate_hook( + @NotNull long ptrToDb, @Nullable PreupdateHookCallback hook + ); /** If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this acts as a proxy for C's sqlite3_preupdate_hook(), else it returns null with no side effects. */ - @Canonical - public static native PreupdateHookCallback sqlite3_preupdate_hook( + public static PreupdateHookCallback sqlite3_preupdate_hook( @NotNull sqlite3 db, @Nullable PreupdateHookCallback hook - ); + ){ + return sqlite3_preupdate_hook(db.getNativePointer(), hook); + } + + static native int sqlite3_preupdate_new(@NotNull long ptrToDb, int col, + @NotNull OutputPointer.sqlite3_value out); /** If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this acts as a proxy for C's sqlite3_preupdate_new(), else it returns SQLITE_MISUSE with no side effects. */ - @Canonical - public static native int sqlite3_preupdate_new(@NotNull sqlite3 db, int col, - @NotNull OutputPointer.sqlite3_value out); + public static int sqlite3_preupdate_new(@NotNull sqlite3 db, int col, + @NotNull OutputPointer.sqlite3_value out){ + return sqlite3_preupdate_new(db.getNativePointer(), col, out); + } /** Convenience wrapper for the 3-arg sqlite3_preupdate_new() which returns @@ -1163,18 +1323,22 @@ public final class SQLite3Jni { */ public static sqlite3_value sqlite3_preupdate_new(@NotNull sqlite3 db, int col){ final OutputPointer.sqlite3_value out = new OutputPointer.sqlite3_value(); - sqlite3_preupdate_new(db, col, out); + sqlite3_preupdate_new(db.getNativePointer(), col, out); return out.take(); } + static native int sqlite3_preupdate_old(@NotNull long ptrToDb, int col, + @NotNull OutputPointer.sqlite3_value out); + /** If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this acts as a proxy for C's sqlite3_preupdate_old(), else it returns SQLITE_MISUSE with no side effects. */ - @Canonical - public static native int sqlite3_preupdate_old(@NotNull sqlite3 db, int col, - @NotNull OutputPointer.sqlite3_value out); + public static int sqlite3_preupdate_old(@NotNull sqlite3 db, int col, + @NotNull OutputPointer.sqlite3_value out){ + return sqlite3_preupdate_old(db.getNativePointer(), col, out); + } /** Convenience wrapper for the 3-arg sqlite3_preupdate_old() which returns @@ -1182,22 +1346,18 @@ public final class SQLite3Jni { */ public static sqlite3_value sqlite3_preupdate_old(@NotNull sqlite3 db, int col){ final OutputPointer.sqlite3_value out = new OutputPointer.sqlite3_value(); - sqlite3_preupdate_old(db, col, out); + sqlite3_preupdate_old(db.getNativePointer(), col, out); return out.take(); } - @Canonical public static native void sqlite3_progress_handler( @NotNull sqlite3 db, int n, @Nullable ProgressHandlerCallback h ); - @Canonical public static native void sqlite3_randomness(byte[] target); - @Canonical public static native int sqlite3_release_memory(int n); - @Canonical public static native int sqlite3_reset(@NotNull sqlite3_stmt stmt); /** @@ -1205,10 +1365,8 @@ public final class SQLite3Jni { extensions are currently running. (The JNI-level list of extensions cannot be manipulated while it is being traversed.) */ - @Canonical public static native void sqlite3_reset_auto_extension(); - @Canonical public static native void sqlite3_result_double( @NotNull sqlite3_context cx, double v ); @@ -1220,19 +1378,16 @@ public final class SQLite3Jni { results in the C-level sqlite3_result_error() being called with a complaint about the invalid argument. */ - @Canonical - private static native void sqlite3_result_error( + static native void sqlite3_result_error( @NotNull sqlite3_context cx, @NotNull byte[] msg, int eTextRep ); - @Canonical public static void sqlite3_result_error( @NotNull sqlite3_context cx, @NotNull byte[] utf8 ){ sqlite3_result_error(cx, utf8, SQLITE_UTF8); } - @Canonical public static void sqlite3_result_error( @NotNull sqlite3_context cx, @NotNull String msg ){ @@ -1265,32 +1420,26 @@ public final class SQLite3Jni { sqlite3_result_error(cx, e.toString()); } - @Canonical public static native void sqlite3_result_error_toobig( @NotNull sqlite3_context cx ); - @Canonical public static native void sqlite3_result_error_nomem( @NotNull sqlite3_context cx ); - @Canonical public static native void sqlite3_result_error_code( @NotNull sqlite3_context cx, int c ); - @Canonical public static native void sqlite3_result_null( @NotNull sqlite3_context cx ); - @Canonical public static native void sqlite3_result_int( @NotNull sqlite3_context cx, int v ); - @Canonical public static native void sqlite3_result_int64( @NotNull sqlite3_context cx, long v ); @@ -1375,17 +1524,14 @@ public final class SQLite3Jni { else sqlite3_result_blob(cx, blob, blob.length); } - @Canonical public static native void sqlite3_result_value( @NotNull sqlite3_context cx, @NotNull sqlite3_value v ); - @Canonical public static native void sqlite3_result_zeroblob( @NotNull sqlite3_context cx, int n ); - @Canonical public static native int sqlite3_result_zeroblob64( @NotNull sqlite3_context cx, long n ); @@ -1394,12 +1540,10 @@ public final class SQLite3Jni { This overload is private because its final parameter is arguably unnecessary in Java. */ - @Canonical private static native void sqlite3_result_blob( @NotNull sqlite3_context cx, @Nullable byte[] blob, int maxLen ); - @Canonical public static void sqlite3_result_blob( @NotNull sqlite3_context cx, @Nullable byte[] blob ){ @@ -1424,12 +1568,10 @@ public final class SQLite3Jni {

This overload is private because its final parameter is arguably unnecessary in Java.

*/ - @Canonical private static native void sqlite3_result_blob64( @NotNull sqlite3_context cx, @Nullable byte[] blob, long maxLen ); - @Canonical public static void sqlite3_result_blob64( @NotNull sqlite3_context cx, @Nullable byte[] blob ){ @@ -1440,19 +1582,16 @@ public final class SQLite3Jni { This overload is private because its final parameter is arguably unnecessary in Java. */ - @Canonical private static native void sqlite3_result_text( @NotNull sqlite3_context cx, @Nullable byte[] utf8, int maxLen ); - @Canonical public static void sqlite3_result_text( @NotNull sqlite3_context cx, @Nullable byte[] utf8 ){ sqlite3_result_text(cx, utf8, null==utf8 ? 0 : utf8.length); } - @Canonical public static void sqlite3_result_text( @NotNull sqlite3_context cx, @Nullable String text ){ @@ -1486,7 +1625,6 @@ public final class SQLite3Jni { This overload is private because its maxLength parameter is arguably unnecessary in Java. */ - @Canonical private static native void sqlite3_result_text64( @NotNull sqlite3_context cx, @Nullable byte[] text, long maxLength, int encoding @@ -1496,14 +1634,13 @@ public final class SQLite3Jni { Sets the current UDF result to the given bytes, which are assumed be encoded in UTF-16 using the platform's byte order. */ - @Canonical public static void sqlite3_result_text16( @NotNull sqlite3_context cx, @Nullable byte[] utf16 ){ - sqlite3_result_text64(cx, utf16, utf16.length, SQLITE_UTF16); + if(null == utf16) sqlite3_result_null(cx); + else sqlite3_result_text64(cx, utf16, utf16.length, SQLITE_UTF16); } - @Canonical public static void sqlite3_result_text16( @NotNull sqlite3_context cx, @Nullable String text ){ @@ -1514,22 +1651,24 @@ public final class SQLite3Jni { } } - @Canonical - public static native RollbackHookCallback sqlite3_rollback_hook( - @NotNull sqlite3 db, @Nullable RollbackHookCallback hook + static native RollbackHookCallback sqlite3_rollback_hook( + @NotNull long ptrToDb, @Nullable RollbackHookCallback hook ); - @Canonical + public static RollbackHookCallback sqlite3_rollback_hook( + @NotNull sqlite3 db, @Nullable RollbackHookCallback hook + ){ + return sqlite3_rollback_hook(db.getNativePointer(), hook); + } + public static native int sqlite3_set_authorizer( @NotNull sqlite3 db, @Nullable AuthorizerCallback auth ); - @Canonical public static native void sqlite3_set_auxdata( @NotNull sqlite3_context cx, int n, @Nullable Object data ); - @Canonical public static native void sqlite3_set_last_insert_rowid( @NotNull sqlite3 db, long rowid ); @@ -1544,45 +1683,44 @@ public final class SQLite3Jni { to use those objects after this routine is called invoked undefined behavior. */ - @Canonical public static synchronized native int sqlite3_shutdown(); - @Canonical public static native int sqlite3_sleep(int ms); - @Canonical public static native String sqlite3_sourceid(); - @Canonical public static native String sqlite3_sql(@NotNull sqlite3_stmt stmt); - @Canonical + //! Consider removing this. We can use sqlite3_status64() instead, + // or use that one's impl with this one's name. public static native int sqlite3_status( int op, @NotNull OutputPointer.Int32 pCurrent, @NotNull OutputPointer.Int32 pHighwater, boolean reset ); - @Canonical public static native int sqlite3_status64( int op, @NotNull OutputPointer.Int64 pCurrent, @NotNull OutputPointer.Int64 pHighwater, boolean reset ); - @Canonical public static native int sqlite3_step(@NotNull sqlite3_stmt stmt); - @Canonical - public static native int sqlite3_stmt_explain( - @NotNull sqlite3_stmt stmt, int op - ); + public static native boolean sqlite3_stmt_busy(@NotNull sqlite3_stmt stmt); - @Canonical - public static native int sqlite3_stmt_isexplain(@NotNull sqlite3_stmt stmt); + static native int sqlite3_stmt_explain(@NotNull long ptrToStmt, int op); + + public static int sqlite3_stmt_explain(@NotNull sqlite3_stmt stmt, int op){ + return sqlite3_stmt_explain(stmt.getNativePointer(), op); + } + + static native int sqlite3_stmt_isexplain(@NotNull long ptrToStmt); + + public static int sqlite3_stmt_isexplain(@NotNull sqlite3_stmt stmt){ + return sqlite3_stmt_isexplain(stmt.getNativePointer()); + } - @Canonical public static native boolean sqlite3_stmt_readonly(@NotNull sqlite3_stmt stmt); - @Canonical public static native int sqlite3_stmt_status( @NotNull sqlite3_stmt stmt, int op, boolean reset ); @@ -1598,45 +1736,39 @@ public final class SQLite3Jni { (sqlite3_strglob(String,String)) than to do that in C, so that signature is the public-facing one. */ - @Canonical private static native int sqlite3_strglob( @NotNull byte[] glob, @NotNull byte[] nullTerminatedUtf8 ); - @Canonical public static int sqlite3_strglob( @NotNull String glob, @NotNull String txt ){ - return sqlite3_strglob( - (glob+"\0").getBytes(StandardCharsets.UTF_8), - (txt+"\0").getBytes(StandardCharsets.UTF_8) - ); + return sqlite3_strglob(nulTerminateUtf8(glob), + nulTerminateUtf8(txt)); } /** The LIKE counterpart of the private sqlite3_strglob() method. */ - @Canonical private static native int sqlite3_strlike( @NotNull byte[] glob, @NotNull byte[] nullTerminatedUtf8, int escChar ); - @Canonical public static int sqlite3_strlike( @NotNull String glob, @NotNull String txt, char escChar ){ - return sqlite3_strlike( - (glob+"\0").getBytes(StandardCharsets.UTF_8), - (txt+"\0").getBytes(StandardCharsets.UTF_8), - (int)escChar - ); + return sqlite3_strlike(nulTerminateUtf8(glob), + nulTerminateUtf8(txt), + (int)escChar); } - @Canonical - public static native int sqlite3_system_errno(@NotNull sqlite3 db); + static native int sqlite3_system_errno(@NotNull long ptrToDb); + + public static int sqlite3_system_errno(@NotNull sqlite3 db){ + return sqlite3_system_errno(db.getNativePointer()); + } - @Canonical public static native int sqlite3_table_column_metadata( @NotNull sqlite3 db, @NotNull String zDbName, @NotNull String zTableName, @NotNull String zColumnName, @@ -1675,39 +1807,47 @@ public final class SQLite3Jni { ) ? out : null; } - @Canonical public static native int sqlite3_threadsafe(); - @Canonical - public static native int sqlite3_total_changes(@NotNull sqlite3 db); + static native int sqlite3_total_changes(@NotNull long ptrToDb); - @Canonical - public static native long sqlite3_total_changes64(@NotNull sqlite3 db); + public static int sqlite3_total_changes(@NotNull sqlite3 db){ + return sqlite3_total_changes(db.getNativePointer()); + } + + static native long sqlite3_total_changes64(@NotNull long ptrToDb); + + public static long sqlite3_total_changes64(@NotNull sqlite3 db){ + return sqlite3_total_changes64(db.getNativePointer()); + } /** Works like C's sqlite3_trace_v2() except that the 3rd argument to that function is elided here because the roles of that functions' 3rd and 4th arguments are encapsulated in the final argument to this function. -

Unlike the C API, which is documented as always returning 0, this - implementation returns non-0 if initialization of the tracer - mapping state fails. +

Unlike the C API, which is documented as always returning 0, + this implementation returns non-0 if initialization of the tracer + mapping state fails (e.g. on OOM). */ - @Canonical public static native int sqlite3_trace_v2( @NotNull sqlite3 db, int traceMask, @Nullable TraceV2Callback tracer ); - @Canonical public static native int sqlite3_txn_state( @NotNull sqlite3 db, @Nullable String zSchema ); - @Canonical - public static native UpdateHookCallback sqlite3_update_hook( - @NotNull sqlite3 db, @Nullable UpdateHookCallback hook + static native UpdateHookCallback sqlite3_update_hook( + @NotNull long ptrToDb, @Nullable UpdateHookCallback hook ); + public static UpdateHookCallback sqlite3_update_hook( + @NotNull sqlite3 db, @Nullable UpdateHookCallback hook + ){ + return sqlite3_update_hook(db.getNativePointer(), hook); + } + /* Note that: @@ -1718,34 +1858,67 @@ public final class SQLite3Jni { sqlite3_create_function(). */ - @Canonical - public static native byte[] sqlite3_value_blob(@NotNull sqlite3_value v); + static native byte[] sqlite3_value_blob(@NotNull long ptrToValue); - @Canonical - public static native int sqlite3_value_bytes(@NotNull sqlite3_value v); + public static byte[] sqlite3_value_blob(@NotNull sqlite3_value v){ + return sqlite3_value_blob(v.getNativePointer()); + } - @Canonical - public static native int sqlite3_value_bytes16(@NotNull sqlite3_value v); + static native int sqlite3_value_bytes(@NotNull long ptrToValue); - @Canonical - public static native double sqlite3_value_double(@NotNull sqlite3_value v); + public static int sqlite3_value_bytes(@NotNull sqlite3_value v){ + return sqlite3_value_bytes(v.getNativePointer()); + } - @Canonical - public static native sqlite3_value sqlite3_value_dup( - @NotNull sqlite3_value v - ); + static native int sqlite3_value_bytes16(@NotNull long ptrToValue); - @Canonical - public static native int sqlite3_value_encoding(@NotNull sqlite3_value v); + public static int sqlite3_value_bytes16(@NotNull sqlite3_value v){ + return sqlite3_value_bytes16(v.getNativePointer()); + } - @Canonical - public static native void sqlite3_value_free(@Nullable sqlite3_value v); + static native double sqlite3_value_double(@NotNull long ptrToValue); - @Canonical - public static native int sqlite3_value_int(@NotNull sqlite3_value v); + public static double sqlite3_value_double(@NotNull sqlite3_value v){ + return sqlite3_value_double(v.getNativePointer()); + } - @Canonical - public static native long sqlite3_value_int64(@NotNull sqlite3_value v); + static native sqlite3_value sqlite3_value_dup(@NotNull long ptrToValue); + + public static sqlite3_value sqlite3_value_dup(@NotNull sqlite3_value v){ + return sqlite3_value_dup(v.getNativePointer()); + } + + static native int sqlite3_value_encoding(@NotNull long ptrToValue); + + public static int sqlite3_value_encoding(@NotNull sqlite3_value v){ + return sqlite3_value_encoding(v.getNativePointer()); + } + + static native void sqlite3_value_free(@Nullable long ptrToValue); + + public static void sqlite3_value_free(@Nullable sqlite3_value v){ + sqlite3_value_free(v.getNativePointer()); + } + + static native boolean sqlite3_value_frombind(@NotNull long ptrToValue); + + public static boolean sqlite3_value_frombind(@NotNull sqlite3_value v){ + return sqlite3_value_frombind(v.getNativePointer()); + } + + static native int sqlite3_value_int(@NotNull long ptrToValue); + + public static int sqlite3_value_int(@NotNull sqlite3_value v){ + return sqlite3_value_int(v.getNativePointer()); + } + + static native long sqlite3_value_int64(@NotNull long ptrToValue); + + public static long sqlite3_value_int64(@NotNull sqlite3_value v){ + return sqlite3_value_int64(v.getNativePointer()); + } + + static native Object sqlite3_value_java_object(@NotNull long ptrToValue); /** If the given value was set using {@link @@ -1755,9 +1928,9 @@ public final class SQLite3Jni {

It is up to the caller to inspect the object to determine its type, and cast it if necessary. */ - public static native Object sqlite3_value_java_object( - @NotNull sqlite3_value v - ); + public static Object sqlite3_value_java_object(@NotNull sqlite3_value v){ + return sqlite3_value_java_object(v.getNativePointer()); + } /** A variant of sqlite3_value_java_object() which returns the @@ -1771,32 +1944,47 @@ public final class SQLite3Jni { return type.isInstance(o) ? (T)o : null; } + static native int sqlite3_value_nochange(@NotNull long ptrToValue); + + public static int sqlite3_value_nochange(@NotNull sqlite3_value v){ + return sqlite3_value_nochange(v.getNativePointer()); + } + + static native int sqlite3_value_numeric_type(@NotNull long ptrToValue); + + public static int sqlite3_value_numeric_type(@NotNull sqlite3_value v){ + return sqlite3_value_numeric_type(v.getNativePointer()); + } + + static native int sqlite3_value_subtype(@NotNull long ptrToValue); + + public static int sqlite3_value_subtype(@NotNull sqlite3_value v){ + return sqlite3_value_subtype(v.getNativePointer()); + } + + static native byte[] sqlite3_value_text(@NotNull long ptrToValue); + /** Functions identially to the C API, and this note is just to stress that the returned bytes are encoded as UTF-8. It returns null if the underlying C-level sqlite3_value_text() returns NULL or on allocation error. */ - @Canonical - public static native byte[] sqlite3_value_text(@NotNull sqlite3_value v); + public static byte[] sqlite3_value_text(@NotNull sqlite3_value v){ + return sqlite3_value_text(v.getNativePointer()); + } - @Canonical - public static native String sqlite3_value_text16(@NotNull sqlite3_value v); + static native String sqlite3_value_text16(@NotNull long ptrToValue); - @Canonical - public static native int sqlite3_value_type(@NotNull sqlite3_value v); + public static String sqlite3_value_text16(@NotNull sqlite3_value v){ + return sqlite3_value_text16(v.getNativePointer()); + } - @Canonical - public static native int sqlite3_value_numeric_type(@NotNull sqlite3_value v); + static native int sqlite3_value_type(@NotNull long ptrToValue); - @Canonical - public static native int sqlite3_value_nochange(@NotNull sqlite3_value v); - - @Canonical - public static native int sqlite3_value_frombind(@NotNull sqlite3_value v); - - @Canonical - public static native int sqlite3_value_subtype(@NotNull sqlite3_value v); + public static int sqlite3_value_type(@NotNull sqlite3_value v){ + return sqlite3_value_type(v.getNativePointer()); + } /** This is NOT part of the public API. It exists solely as a place @@ -2041,27 +2229,29 @@ public final class SQLite3Jni { public static final int SQLITE_LIMIT_WORKER_THREADS = 11; // open flags - public static final int SQLITE_OPEN_READONLY = 1; - public static final int SQLITE_OPEN_READWRITE = 2; - public static final int SQLITE_OPEN_CREATE = 4; - public static final int SQLITE_OPEN_URI = 64; - public static final int SQLITE_OPEN_MEMORY = 128; - public static final int SQLITE_OPEN_NOMUTEX = 32768; - public static final int SQLITE_OPEN_FULLMUTEX = 65536; - public static final int SQLITE_OPEN_SHAREDCACHE = 131072; - public static final int SQLITE_OPEN_PRIVATECACHE = 262144; - public static final int SQLITE_OPEN_EXRESCODE = 33554432; - public static final int SQLITE_OPEN_NOFOLLOW = 16777216; - public static final int SQLITE_OPEN_MAIN_DB = 256; - public static final int SQLITE_OPEN_MAIN_JOURNAL = 2048; - public static final int SQLITE_OPEN_TEMP_DB = 512; - public static final int SQLITE_OPEN_TEMP_JOURNAL = 4096; - public static final int SQLITE_OPEN_TRANSIENT_DB = 1024; - public static final int SQLITE_OPEN_SUBJOURNAL = 8192; - public static final int SQLITE_OPEN_SUPER_JOURNAL = 16384; - public static final int SQLITE_OPEN_WAL = 524288; - public static final int SQLITE_OPEN_DELETEONCLOSE = 8; - public static final int SQLITE_OPEN_EXCLUSIVE = 16; + + public static final int SQLITE_OPEN_READONLY = 0x00000001 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_READWRITE = 0x00000002 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_CREATE = 0x00000004 /* Ok for sqlite3_open_v2() */; + //public static final int SQLITE_OPEN_DELETEONCLOSE = 0x00000008 /* VFS only */; + //public static final int SQLITE_OPEN_EXCLUSIVE = 0x00000010 /* VFS only */; + //public static final int SQLITE_OPEN_AUTOPROXY = 0x00000020 /* VFS only */; + public static final int SQLITE_OPEN_URI = 0x00000040 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_MEMORY = 0x00000080 /* Ok for sqlite3_open_v2() */; + //public static final int SQLITE_OPEN_MAIN_DB = 0x00000100 /* VFS only */; + //public static final int SQLITE_OPEN_TEMP_DB = 0x00000200 /* VFS only */; + //public static final int SQLITE_OPEN_TRANSIENT_DB = 0x00000400 /* VFS only */; + //public static final int SQLITE_OPEN_MAIN_JOURNAL = 0x00000800 /* VFS only */; + //public static final int SQLITE_OPEN_TEMP_JOURNAL = 0x00001000 /* VFS only */; + //public static final int SQLITE_OPEN_SUBJOURNAL = 0x00002000 /* VFS only */; + //public static final int SQLITE_OPEN_SUPER_JOURNAL = 0x00004000 /* VFS only */; + public static final int SQLITE_OPEN_NOMUTEX = 0x00008000 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_FULLMUTEX = 0x00010000 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_SHAREDCACHE = 0x00020000 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_PRIVATECACHE = 0x00040000 /* Ok for sqlite3_open_v2() */; + //public static final int SQLITE_OPEN_WAL = 0x00080000 /* VFS only */; + public static final int SQLITE_OPEN_NOFOLLOW = 0x01000000 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_EXRESCODE = 0x02000000 /* Extended result codes */; // prepare flags public static final int SQLITE_PREPARE_PERSISTENT = 1; @@ -2221,9 +2411,9 @@ public final class SQLite3Jni { public static final int SQLITE_TXN_WRITE = 2; // udf flags - public static final int SQLITE_DETERMINISTIC = 2048; - public static final int SQLITE_DIRECTONLY = 524288; - public static final int SQLITE_INNOCUOUS = 2097152; + public static final int SQLITE_DETERMINISTIC = 0x000000800; + public static final int SQLITE_DIRECTONLY = 0x000080000; + public static final int SQLITE_INNOCUOUS = 0x000200000; // virtual tables public static final int SQLITE_INDEX_SCAN_UNIQUE = 1; diff --git a/ext/jni/src/org/sqlite/jni/CallbackProxy.java b/ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java similarity index 98% rename from ext/jni/src/org/sqlite/jni/CallbackProxy.java rename to ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java index 086c2f8e5d..0495702561 100644 --- a/ext/jni/src/org/sqlite/jni/CallbackProxy.java +++ b/ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** This marker interface exists soley for use as a documentation and class-grouping tool. It should be applied to interfaces or diff --git a/ext/jni/src/org/sqlite/jni/CollationCallback.java b/ext/jni/src/org/sqlite/jni/capi/CollationCallback.java similarity index 90% rename from ext/jni/src/org/sqlite/jni/CollationCallback.java rename to ext/jni/src/org/sqlite/jni/capi/CollationCallback.java index 7f0e79a3fa..ed8bd09475 100644 --- a/ext/jni/src/org/sqlite/jni/CollationCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/CollationCallback.java @@ -11,11 +11,11 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; import org.sqlite.jni.annotation.NotNull; /** - Callback for use with {@link SQLite3Jni#sqlite3_create_collation}. + Callback for use with {@link CApi#sqlite3_create_collation}. @see AbstractCollationCallback */ diff --git a/ext/jni/src/org/sqlite/jni/CollationNeededCallback.java b/ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java similarity index 89% rename from ext/jni/src/org/sqlite/jni/CollationNeededCallback.java rename to ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java index b72cf1ba53..fe61fe5065 100644 --- a/ext/jni/src/org/sqlite/jni/CollationNeededCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with {@link SQLite3Jni#sqlite3_collation_needed}. + Callback for use with {@link CApi#sqlite3_collation_needed}. */ public interface CollationNeededCallback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/CommitHookCallback.java b/ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java similarity index 87% rename from ext/jni/src/org/sqlite/jni/CommitHookCallback.java rename to ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java index 2e9a68d25d..24373bdf2b 100644 --- a/ext/jni/src/org/sqlite/jni/CommitHookCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with {@link SQLite3Jni#sqlite3_commit_hook}. + Callback for use with {@link CApi#sqlite3_commit_hook}. */ public interface CommitHookCallback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/ConfigLogCallback.java b/ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java similarity index 84% rename from ext/jni/src/org/sqlite/jni/ConfigLogCallback.java rename to ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java index 2198f1e104..6513b0730d 100644 --- a/ext/jni/src/org/sqlite/jni/ConfigLogCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** A callback for use with sqlite3_config(). @@ -19,7 +19,7 @@ package org.sqlite.jni; public interface ConfigLogCallback { /** Must function as described for a C-level callback for - {@link SQLite3Jni#sqlite3_config(ConfigLogCallback)}, with the slight signature change. + {@link CApi#sqlite3_config(ConfigLogCallback)}, with the slight signature change. */ void call(int errCode, String msg); } diff --git a/ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java b/ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java similarity index 84% rename from ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java rename to ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java index 9bdd209a7a..df753e6513 100644 --- a/ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** A callback for use with sqlite3_config(). @@ -19,7 +19,7 @@ package org.sqlite.jni; public interface ConfigSqllogCallback { /** Must function as described for a C-level callback for - {@link SQLite3Jni#sqlite3_config(ConfigSqllogCallback)}, with the slight signature change. + {@link CApi#sqlite3_config(ConfigSqllogCallback)}, with the slight signature change. */ void call(sqlite3 db, String msg, int msgType ); } diff --git a/ext/jni/src/org/sqlite/jni/NativePointerHolder.java b/ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java similarity index 74% rename from ext/jni/src/org/sqlite/jni/NativePointerHolder.java rename to ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java index 251eb7faad..e82909e424 100644 --- a/ext/jni/src/org/sqlite/jni/NativePointerHolder.java +++ b/ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** A helper for passing pointers between JNI C code and Java, in @@ -29,5 +29,18 @@ package org.sqlite.jni; public class NativePointerHolder { //! Only set from JNI, where access permissions don't matter. private volatile long nativePointer = 0; + /** + For use ONLY by package-level APIs which act as proxies for + close/finalize operations. Such ops must call this to zero out + the pointer so that this object is not carrying a stale + pointer. This function returns the prior value of the pointer and + sets it to 0. + */ + final long clearNativePointer() { + final long rv = nativePointer; + nativePointer= 0; + return rv; + } + public final long getNativePointer(){ return nativePointer; } } diff --git a/ext/jni/src/org/sqlite/jni/OutputPointer.java b/ext/jni/src/org/sqlite/jni/capi/OutputPointer.java similarity index 87% rename from ext/jni/src/org/sqlite/jni/OutputPointer.java rename to ext/jni/src/org/sqlite/jni/capi/OutputPointer.java index c6e48ed72f..60b9025386 100644 --- a/ext/jni/src/org/sqlite/jni/OutputPointer.java +++ b/ext/jni/src/org/sqlite/jni/capi/OutputPointer.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** Helper classes for handling JNI output pointers. @@ -49,16 +49,16 @@ public final class OutputPointer { code. */ public static final class sqlite3 { - private org.sqlite.jni.sqlite3 value; + private org.sqlite.jni.capi.sqlite3 value; /** Initializes with a null value. */ public sqlite3(){value = null;} /** Sets the current value to null. */ public void clear(){value = null;} /** Returns the current value. */ - public final org.sqlite.jni.sqlite3 get(){return value;} + public final org.sqlite.jni.capi.sqlite3 get(){return value;} /** Equivalent to calling get() then clear(). */ - public final org.sqlite.jni.sqlite3 take(){ - final org.sqlite.jni.sqlite3 v = value; + public final org.sqlite.jni.capi.sqlite3 take(){ + final org.sqlite.jni.capi.sqlite3 v = value; value = null; return v; } @@ -70,16 +70,16 @@ public final class OutputPointer { code. */ public static final class sqlite3_blob { - private org.sqlite.jni.sqlite3_blob value; + private org.sqlite.jni.capi.sqlite3_blob value; /** Initializes with a null value. */ public sqlite3_blob(){value = null;} /** Sets the current value to null. */ public void clear(){value = null;} /** Returns the current value. */ - public final org.sqlite.jni.sqlite3_blob get(){return value;} + public final org.sqlite.jni.capi.sqlite3_blob get(){return value;} /** Equivalent to calling get() then clear(). */ - public final org.sqlite.jni.sqlite3_blob take(){ - final org.sqlite.jni.sqlite3_blob v = value; + public final org.sqlite.jni.capi.sqlite3_blob take(){ + final org.sqlite.jni.capi.sqlite3_blob v = value; value = null; return v; } @@ -92,16 +92,16 @@ public final class OutputPointer { code. */ public static final class sqlite3_stmt { - private org.sqlite.jni.sqlite3_stmt value; + private org.sqlite.jni.capi.sqlite3_stmt value; /** Initializes with a null value. */ public sqlite3_stmt(){value = null;} /** Sets the current value to null. */ public void clear(){value = null;} /** Returns the current value. */ - public final org.sqlite.jni.sqlite3_stmt get(){return value;} + public final org.sqlite.jni.capi.sqlite3_stmt get(){return value;} /** Equivalent to calling get() then clear(). */ - public final org.sqlite.jni.sqlite3_stmt take(){ - final org.sqlite.jni.sqlite3_stmt v = value; + public final org.sqlite.jni.capi.sqlite3_stmt take(){ + final org.sqlite.jni.capi.sqlite3_stmt v = value; value = null; return v; } @@ -114,16 +114,16 @@ public final class OutputPointer { code. */ public static final class sqlite3_value { - private org.sqlite.jni.sqlite3_value value; + private org.sqlite.jni.capi.sqlite3_value value; /** Initializes with a null value. */ public sqlite3_value(){value = null;} /** Sets the current value to null. */ public void clear(){value = null;} /** Returns the current value. */ - public final org.sqlite.jni.sqlite3_value get(){return value;} + public final org.sqlite.jni.capi.sqlite3_value get(){return value;} /** Equivalent to calling get() then clear(). */ - public final org.sqlite.jni.sqlite3_value take(){ - final org.sqlite.jni.sqlite3_value v = value; + public final org.sqlite.jni.capi.sqlite3_value take(){ + final org.sqlite.jni.capi.sqlite3_value v = value; value = null; return v; } diff --git a/ext/jni/src/org/sqlite/jni/PrepareMultiCallback.java b/ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java similarity index 88% rename from ext/jni/src/org/sqlite/jni/PrepareMultiCallback.java rename to ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java index d2d56157c4..1c805a9b16 100644 --- a/ext/jni/src/org/sqlite/jni/PrepareMultiCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with {@link SQLite3Jni#sqlite3_prepare_multi}. + Callback for use with {@link CApi#sqlite3_prepare_multi}. */ public interface PrepareMultiCallback extends CallbackProxy { @@ -53,7 +53,7 @@ public interface PrepareMultiCallback extends CallbackProxy { try { return this.p.call(st); }finally{ - SQLite3Jni.sqlite3_finalize(st); + CApi.sqlite3_finalize(st); } } } @@ -70,9 +70,9 @@ public interface PrepareMultiCallback extends CallbackProxy { else the result of the final step is returned. */ @Override public int call(sqlite3_stmt st){ - int rc = SQLite3Jni.SQLITE_DONE; - while( SQLite3Jni.SQLITE_ROW == (rc = SQLite3Jni.sqlite3_step(st)) ){} - return SQLite3Jni.SQLITE_DONE==rc ? 0 : rc; + int rc = CApi.SQLITE_DONE; + while( CApi.SQLITE_ROW == (rc = CApi.sqlite3_step(st)) ){} + return CApi.SQLITE_DONE==rc ? 0 : rc; } } } diff --git a/ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java b/ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java similarity index 88% rename from ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java rename to ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java index a606139328..99d3fb0351 100644 --- a/ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with {@link SQLite3Jni#sqlite3_preupdate_hook}. + Callback for use with {@link CApi#sqlite3_preupdate_hook}. */ public interface PreupdateHookCallback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java b/ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java similarity index 88% rename from ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java rename to ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java index bc15377037..464baa2e3d 100644 --- a/ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with {@link SQLite3Jni#sqlite3_progress_handler}. + Callback for use with {@link CApi#sqlite3_progress_handler}. */ public interface ProgressHandlerCallback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/capi/ResultCode.java b/ext/jni/src/org/sqlite/jni/capi/ResultCode.java new file mode 100644 index 0000000000..5a8b2e6a18 --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/capi/ResultCode.java @@ -0,0 +1,155 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + This enum contains all of the core and "extended" result codes used + by the sqlite3 library. It is provided not for use with the C-style + API (with which it won't work) but for higher-level code which may + find it useful to map SQLite result codes to human-readable names. +*/ +public enum ResultCode { + SQLITE_OK(CApi.SQLITE_OK), + SQLITE_ERROR(CApi.SQLITE_ERROR), + SQLITE_INTERNAL(CApi.SQLITE_INTERNAL), + SQLITE_PERM(CApi.SQLITE_PERM), + SQLITE_ABORT(CApi.SQLITE_ABORT), + SQLITE_BUSY(CApi.SQLITE_BUSY), + SQLITE_LOCKED(CApi.SQLITE_LOCKED), + SQLITE_NOMEM(CApi.SQLITE_NOMEM), + SQLITE_READONLY(CApi.SQLITE_READONLY), + SQLITE_INTERRUPT(CApi.SQLITE_INTERRUPT), + SQLITE_IOERR(CApi.SQLITE_IOERR), + SQLITE_CORRUPT(CApi.SQLITE_CORRUPT), + SQLITE_NOTFOUND(CApi.SQLITE_NOTFOUND), + SQLITE_FULL(CApi.SQLITE_FULL), + SQLITE_CANTOPEN(CApi.SQLITE_CANTOPEN), + SQLITE_PROTOCOL(CApi.SQLITE_PROTOCOL), + SQLITE_EMPTY(CApi.SQLITE_EMPTY), + SQLITE_SCHEMA(CApi.SQLITE_SCHEMA), + SQLITE_TOOBIG(CApi.SQLITE_TOOBIG), + SQLITE_CONSTRAINT(CApi.SQLITE_CONSTRAINT), + SQLITE_MISMATCH(CApi.SQLITE_MISMATCH), + SQLITE_MISUSE(CApi.SQLITE_MISUSE), + SQLITE_NOLFS(CApi.SQLITE_NOLFS), + SQLITE_AUTH(CApi.SQLITE_AUTH), + SQLITE_FORMAT(CApi.SQLITE_FORMAT), + SQLITE_RANGE(CApi.SQLITE_RANGE), + SQLITE_NOTADB(CApi.SQLITE_NOTADB), + SQLITE_NOTICE(CApi.SQLITE_NOTICE), + SQLITE_WARNING(CApi.SQLITE_WARNING), + SQLITE_ROW(CApi.SQLITE_ROW), + SQLITE_DONE(CApi.SQLITE_DONE), + SQLITE_ERROR_MISSING_COLLSEQ(CApi.SQLITE_ERROR_MISSING_COLLSEQ), + SQLITE_ERROR_RETRY(CApi.SQLITE_ERROR_RETRY), + SQLITE_ERROR_SNAPSHOT(CApi.SQLITE_ERROR_SNAPSHOT), + SQLITE_IOERR_READ(CApi.SQLITE_IOERR_READ), + SQLITE_IOERR_SHORT_READ(CApi.SQLITE_IOERR_SHORT_READ), + SQLITE_IOERR_WRITE(CApi.SQLITE_IOERR_WRITE), + SQLITE_IOERR_FSYNC(CApi.SQLITE_IOERR_FSYNC), + SQLITE_IOERR_DIR_FSYNC(CApi.SQLITE_IOERR_DIR_FSYNC), + SQLITE_IOERR_TRUNCATE(CApi.SQLITE_IOERR_TRUNCATE), + SQLITE_IOERR_FSTAT(CApi.SQLITE_IOERR_FSTAT), + SQLITE_IOERR_UNLOCK(CApi.SQLITE_IOERR_UNLOCK), + SQLITE_IOERR_RDLOCK(CApi.SQLITE_IOERR_RDLOCK), + SQLITE_IOERR_DELETE(CApi.SQLITE_IOERR_DELETE), + SQLITE_IOERR_BLOCKED(CApi.SQLITE_IOERR_BLOCKED), + SQLITE_IOERR_NOMEM(CApi.SQLITE_IOERR_NOMEM), + SQLITE_IOERR_ACCESS(CApi.SQLITE_IOERR_ACCESS), + SQLITE_IOERR_CHECKRESERVEDLOCK(CApi.SQLITE_IOERR_CHECKRESERVEDLOCK), + SQLITE_IOERR_LOCK(CApi.SQLITE_IOERR_LOCK), + SQLITE_IOERR_CLOSE(CApi.SQLITE_IOERR_CLOSE), + SQLITE_IOERR_DIR_CLOSE(CApi.SQLITE_IOERR_DIR_CLOSE), + SQLITE_IOERR_SHMOPEN(CApi.SQLITE_IOERR_SHMOPEN), + SQLITE_IOERR_SHMSIZE(CApi.SQLITE_IOERR_SHMSIZE), + SQLITE_IOERR_SHMLOCK(CApi.SQLITE_IOERR_SHMLOCK), + SQLITE_IOERR_SHMMAP(CApi.SQLITE_IOERR_SHMMAP), + SQLITE_IOERR_SEEK(CApi.SQLITE_IOERR_SEEK), + SQLITE_IOERR_DELETE_NOENT(CApi.SQLITE_IOERR_DELETE_NOENT), + SQLITE_IOERR_MMAP(CApi.SQLITE_IOERR_MMAP), + SQLITE_IOERR_GETTEMPPATH(CApi.SQLITE_IOERR_GETTEMPPATH), + SQLITE_IOERR_CONVPATH(CApi.SQLITE_IOERR_CONVPATH), + SQLITE_IOERR_VNODE(CApi.SQLITE_IOERR_VNODE), + SQLITE_IOERR_AUTH(CApi.SQLITE_IOERR_AUTH), + SQLITE_IOERR_BEGIN_ATOMIC(CApi.SQLITE_IOERR_BEGIN_ATOMIC), + SQLITE_IOERR_COMMIT_ATOMIC(CApi.SQLITE_IOERR_COMMIT_ATOMIC), + SQLITE_IOERR_ROLLBACK_ATOMIC(CApi.SQLITE_IOERR_ROLLBACK_ATOMIC), + SQLITE_IOERR_DATA(CApi.SQLITE_IOERR_DATA), + SQLITE_IOERR_CORRUPTFS(CApi.SQLITE_IOERR_CORRUPTFS), + SQLITE_LOCKED_SHAREDCACHE(CApi.SQLITE_LOCKED_SHAREDCACHE), + SQLITE_LOCKED_VTAB(CApi.SQLITE_LOCKED_VTAB), + SQLITE_BUSY_RECOVERY(CApi.SQLITE_BUSY_RECOVERY), + SQLITE_BUSY_SNAPSHOT(CApi.SQLITE_BUSY_SNAPSHOT), + SQLITE_BUSY_TIMEOUT(CApi.SQLITE_BUSY_TIMEOUT), + SQLITE_CANTOPEN_NOTEMPDIR(CApi.SQLITE_CANTOPEN_NOTEMPDIR), + SQLITE_CANTOPEN_ISDIR(CApi.SQLITE_CANTOPEN_ISDIR), + SQLITE_CANTOPEN_FULLPATH(CApi.SQLITE_CANTOPEN_FULLPATH), + SQLITE_CANTOPEN_CONVPATH(CApi.SQLITE_CANTOPEN_CONVPATH), + SQLITE_CANTOPEN_SYMLINK(CApi.SQLITE_CANTOPEN_SYMLINK), + SQLITE_CORRUPT_VTAB(CApi.SQLITE_CORRUPT_VTAB), + SQLITE_CORRUPT_SEQUENCE(CApi.SQLITE_CORRUPT_SEQUENCE), + SQLITE_CORRUPT_INDEX(CApi.SQLITE_CORRUPT_INDEX), + SQLITE_READONLY_RECOVERY(CApi.SQLITE_READONLY_RECOVERY), + SQLITE_READONLY_CANTLOCK(CApi.SQLITE_READONLY_CANTLOCK), + SQLITE_READONLY_ROLLBACK(CApi.SQLITE_READONLY_ROLLBACK), + SQLITE_READONLY_DBMOVED(CApi.SQLITE_READONLY_DBMOVED), + SQLITE_READONLY_CANTINIT(CApi.SQLITE_READONLY_CANTINIT), + SQLITE_READONLY_DIRECTORY(CApi.SQLITE_READONLY_DIRECTORY), + SQLITE_ABORT_ROLLBACK(CApi.SQLITE_ABORT_ROLLBACK), + SQLITE_CONSTRAINT_CHECK(CApi.SQLITE_CONSTRAINT_CHECK), + SQLITE_CONSTRAINT_COMMITHOOK(CApi.SQLITE_CONSTRAINT_COMMITHOOK), + SQLITE_CONSTRAINT_FOREIGNKEY(CApi.SQLITE_CONSTRAINT_FOREIGNKEY), + SQLITE_CONSTRAINT_FUNCTION(CApi.SQLITE_CONSTRAINT_FUNCTION), + SQLITE_CONSTRAINT_NOTNULL(CApi.SQLITE_CONSTRAINT_NOTNULL), + SQLITE_CONSTRAINT_PRIMARYKEY(CApi.SQLITE_CONSTRAINT_PRIMARYKEY), + SQLITE_CONSTRAINT_TRIGGER(CApi.SQLITE_CONSTRAINT_TRIGGER), + SQLITE_CONSTRAINT_UNIQUE(CApi.SQLITE_CONSTRAINT_UNIQUE), + SQLITE_CONSTRAINT_VTAB(CApi.SQLITE_CONSTRAINT_VTAB), + SQLITE_CONSTRAINT_ROWID(CApi.SQLITE_CONSTRAINT_ROWID), + SQLITE_CONSTRAINT_PINNED(CApi.SQLITE_CONSTRAINT_PINNED), + SQLITE_CONSTRAINT_DATATYPE(CApi.SQLITE_CONSTRAINT_DATATYPE), + SQLITE_NOTICE_RECOVER_WAL(CApi.SQLITE_NOTICE_RECOVER_WAL), + SQLITE_NOTICE_RECOVER_ROLLBACK(CApi.SQLITE_NOTICE_RECOVER_ROLLBACK), + SQLITE_WARNING_AUTOINDEX(CApi.SQLITE_WARNING_AUTOINDEX), + SQLITE_AUTH_USER(CApi.SQLITE_AUTH_USER), + SQLITE_OK_LOAD_PERMANENTLY(CApi.SQLITE_OK_LOAD_PERMANENTLY); + + public final int value; + + ResultCode(int rc){ + value = rc; + ResultCodeMap.set(rc, this); + } + + /** + Returns the entry from this enum for the given result code, or + null if no match is found. + */ + public static ResultCode getEntryForInt(int rc){ + return ResultCodeMap.get(rc); + } + + /** + Internal level of indirection required because we cannot initialize + static enum members in an enum before the enum constructor is + invoked. + */ + private static final class ResultCodeMap { + private static final java.util.Map i2e + = new java.util.HashMap<>(); + private static void set(int rc, ResultCode e){ i2e.put(rc, e); } + private static ResultCode get(int rc){ return i2e.get(rc); } + } + +} diff --git a/ext/jni/src/org/sqlite/jni/RollbackHookCallback.java b/ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java similarity index 87% rename from ext/jni/src/org/sqlite/jni/RollbackHookCallback.java rename to ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java index 21600c8057..5ce17e718a 100644 --- a/ext/jni/src/org/sqlite/jni/RollbackHookCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with {@link SQLite3Jni#sqlite3_rollback_hook}. + Callback for use with {@link CApi#sqlite3_rollback_hook}. */ public interface RollbackHookCallback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/SQLFunction.java b/ext/jni/src/org/sqlite/jni/capi/SQLFunction.java similarity index 99% rename from ext/jni/src/org/sqlite/jni/SQLFunction.java rename to ext/jni/src/org/sqlite/jni/capi/SQLFunction.java index 66119ebe55..4806e2fc0c 100644 --- a/ext/jni/src/org/sqlite/jni/SQLFunction.java +++ b/ext/jni/src/org/sqlite/jni/capi/SQLFunction.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** SQLFunction is used in conjunction with the diff --git a/ext/jni/src/org/sqlite/jni/tester/SQLTester.java b/ext/jni/src/org/sqlite/jni/capi/SQLTester.java similarity index 98% rename from ext/jni/src/org/sqlite/jni/tester/SQLTester.java rename to ext/jni/src/org/sqlite/jni/capi/SQLTester.java index 4a97d4974e..81d6106be7 100644 --- a/ext/jni/src/org/sqlite/jni/tester/SQLTester.java +++ b/ext/jni/src/org/sqlite/jni/capi/SQLTester.java @@ -12,16 +12,13 @@ ** This file contains the main application entry pointer for the ** SQLTester framework. */ -package org.sqlite.jni.tester; +package org.sqlite.jni.capi; import java.util.List; import java.util.ArrayList; import java.util.Arrays; import java.nio.charset.StandardCharsets; import java.util.regex.*; -import org.sqlite.jni.*; -import static org.sqlite.jni.SQLite3Jni.*; -import org.sqlite.jni.sqlite3; - +import static org.sqlite.jni.capi.CApi.*; /** Modes for how to escape (or not) column values and names from @@ -71,7 +68,7 @@ class SQLTesterException extends RuntimeException { class DbException extends SQLTesterException { DbException(sqlite3 db, int rc, boolean closeDb){ - super("DB error #"+rc+": "+sqlite3_errmsg16(db),true); + super("DB error #"+rc+": "+sqlite3_errmsg(db),true); if( closeDb ) sqlite3_close_v2(db); } DbException(sqlite3 db, int rc){ @@ -150,12 +147,15 @@ class Outer { } /** - This class provides an application which aims to implement the +

This class provides an application which aims to implement the rudimentary SQL-driven test tool described in the accompanying {@code test-script-interpreter.md}. -

This is a work in progress. - +

This class is an internal testing tool, not part of the public + interface but is (A) in the same package as the library because + access permissions require it to be so and (B) the JDK8 javadoc + offers no way to filter individual classes out of the doc + generation process (it can only exclude packages, but see (A)).

An instance of this application provides a core set of services which TestScript instances use for processing testing logic. @@ -457,8 +457,8 @@ public class SQLTester { } private void appendDbErr(sqlite3 db, StringBuilder sb, int rc){ - sb.append(org.sqlite.jni.ResultCode.getEntryForInt(rc)).append(' '); - final String msg = escapeSqlValue(sqlite3_errmsg16(db)); + sb.append(org.sqlite.jni.capi.ResultCode.getEntryForInt(rc)).append(' '); + final String msg = escapeSqlValue(sqlite3_errmsg(db)); if( '{' == msg.charAt(0) ){ sb.append(msg); }else{ @@ -668,7 +668,7 @@ public class SQLTester { static { System.loadLibrary("sqlite3-jni") /* Interestingly, when SQLTester is the main app, we have to - load that lib from here. The same load from SQLite3Jni does + load that lib from here. The same load from CApi does not happen early enough. Without this, installCustomExtensions() is an unresolved symbol. */; } @@ -932,7 +932,7 @@ class RunCommand extends Command { final int rc = t.execSql(db, false, ResultBufferMode.NONE, ResultRowMode.ONELINE, sql); if( 0!=rc && t.isVerbose() ){ - String msg = sqlite3_errmsg16(db); + String msg = sqlite3_errmsg(db); ts.verbose1(argv[0]," non-fatal command error #",rc,": ", msg,"\nfor SQL:\n",sql); } diff --git a/ext/jni/src/org/sqlite/jni/ScalarFunction.java b/ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java similarity index 91% rename from ext/jni/src/org/sqlite/jni/ScalarFunction.java rename to ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java index 73fb58cda2..95541bdcba 100644 --- a/ext/jni/src/org/sqlite/jni/ScalarFunction.java +++ b/ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** @@ -27,7 +27,7 @@ public abstract class ScalarFunction implements SQLFunction { /** Optionally override to be notified when the UDF is finalized by - SQLite. This implementation does nothing. + SQLite. This default implementation does nothing. */ public void xDestroy() {} } diff --git a/ext/jni/src/org/sqlite/jni/TableColumnMetadata.java b/ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java similarity index 97% rename from ext/jni/src/org/sqlite/jni/TableColumnMetadata.java rename to ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java index 70b7c90ec8..d8b6226ac9 100644 --- a/ext/jni/src/org/sqlite/jni/TableColumnMetadata.java +++ b/ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** A wrapper object for use with sqlite3_table_column_metadata(). diff --git a/ext/jni/src/org/sqlite/jni/Tester1.java b/ext/jni/src/org/sqlite/jni/capi/Tester1.java similarity index 91% rename from ext/jni/src/org/sqlite/jni/Tester1.java rename to ext/jni/src/org/sqlite/jni/capi/Tester1.java index 5e05313c10..6fb28e65b9 100644 --- a/ext/jni/src/org/sqlite/jni/Tester1.java +++ b/ext/jni/src/org/sqlite/jni/capi/Tester1.java @@ -11,8 +11,8 @@ ************************************************************************* ** This file contains a set of tests for the sqlite3 JNI bindings. */ -package org.sqlite.jni; -import static org.sqlite.jni.SQLite3Jni.*; +package org.sqlite.jni.capi; +import static org.sqlite.jni.capi.CApi.*; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.ArrayList; @@ -38,17 +38,6 @@ import java.util.concurrent.Future; @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @interface SingleThreadOnly{} -/** - A helper class which simply holds a single value. Its current use - is for communicating values out of anonymous classes, as doing so - requires a "final" reference. -*/ -class ValueHolder { - public T value; - public ValueHolder(){} - public ValueHolder(T v){value = v;} -} - public class Tester1 implements Runnable { //! True when running in multi-threaded mode. private static boolean mtMode = false; @@ -146,7 +135,7 @@ public class Tester1 implements Runnable { sqlite3 db = out.take(); if( 0!=rc ){ final String msg = - null==db ? sqlite3_errstr(rc) : sqlite3_errmsg16(db); + null==db ? sqlite3_errstr(rc) : sqlite3_errmsg(db); sqlite3_close(db); throw new RuntimeException("Opening db failed: "+msg); } @@ -197,7 +186,7 @@ public class Tester1 implements Runnable { if(SQLITE_ROW==rc || SQLITE_DONE==rc) rc = 0; if( 0!=rc && throwOnError){ throw new RuntimeException("db op failed with rc=" - +rc+": "+sqlite3_errmsg16(db)); + +rc+": "+sqlite3_errmsg(db)); } return rc; } @@ -249,12 +238,18 @@ public class Tester1 implements Runnable { ++metrics.dbOpen; sqlite3 db = out.get(); affirm(0 == rc); - affirm(0 < db.getNativePointer()); + affirm(db.getNativePointer()!=0); sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 1, null) /* This function has different mangled names in jdk8 vs jdk19, and this call is here to ensure that the build fails if it cannot find both names. */; + affirm( 0==sqlite3_db_readonly(db,"main") ); + affirm( 0==sqlite3_db_readonly(db,null) ); + affirm( 0>sqlite3_db_readonly(db,"nope") ); + affirm( 0>sqlite3_db_readonly(null,null) ); + affirm( 0==sqlite3_last_insert_rowid(null) ); + // These interrupt checks are only to make sure that the JNI binding // has the proper exported symbol names. They don't actually test // anything useful. @@ -273,7 +268,7 @@ public class Tester1 implements Runnable { ++metrics.dbOpen; affirm(0 == rc); sqlite3 db = out.get(); - affirm(0 < db.getNativePointer()); + affirm(0 != db.getNativePointer()); sqlite3_close_v2(db); affirm(0 == db.getNativePointer()); } @@ -289,9 +284,6 @@ public class Tester1 implements Runnable { affirm( !sqlite3_stmt_readonly(stmt) ); affirm( db == sqlite3_db_handle(stmt) ); rc = sqlite3_step(stmt); - if( SQLITE_DONE != rc ){ - outln("step failed ??? ",rc, " ",sqlite3_errmsg16(db)); - } affirm(SQLITE_DONE == rc); sqlite3_finalize(stmt); affirm( null == sqlite3_db_handle(stmt) ); @@ -346,7 +338,7 @@ public class Tester1 implements Runnable { stmt = sqlite3_prepare(db, "intentional error"); affirm( null==stmt ); affirm( 0!=sqlite3_errcode(db) ); - affirm( 0==sqlite3_errmsg16(db).indexOf("near \"intentional\"") ); + affirm( 0==sqlite3_errmsg(db).indexOf("near \"intentional\"") ); sqlite3_finalize(stmt); stmt = sqlite3_prepare(db, "/* empty input*/\n-- comments only"); affirm( null==stmt ); @@ -389,65 +381,80 @@ public class Tester1 implements Runnable { affirm(sqlite3_total_changes64(db) > changesT64); stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); affirm( sqlite3_stmt_readonly(stmt) ); + affirm( !sqlite3_stmt_busy(stmt) ); int total2 = 0; while( SQLITE_ROW == sqlite3_step(stmt) ){ + affirm( sqlite3_stmt_busy(stmt) ); total2 += sqlite3_column_int(stmt, 0); sqlite3_value sv = sqlite3_column_value(stmt, 0); affirm( null != sv ); affirm( 0 != sv.getNativePointer() ); affirm( SQLITE_INTEGER == sqlite3_value_type(sv) ); } + affirm( !sqlite3_stmt_busy(stmt) ); sqlite3_finalize(stmt); affirm(total1 == total2); + + // sqlite3_value_frombind() checks... + stmt = prepare(db, "SELECT 1, ?"); + sqlite3_bind_int(stmt, 1, 2); + rc = sqlite3_step(stmt); + affirm( SQLITE_ROW==rc ); + affirm( !sqlite3_value_frombind(sqlite3_column_value(stmt, 0)) ); + affirm( sqlite3_value_frombind(sqlite3_column_value(stmt, 1)) ); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); affirm(0 == db.getNativePointer()); } private void testBindFetchInt64(){ - sqlite3 db = createNewDb(); - execSql(db, "CREATE TABLE t(a)"); - sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); - long total1 = 0; - for(long i = 0xffffffff; i < 0xffffffff + 3; ++i ){ - total1 += i; - sqlite3_bind_int64(stmt, 1, i); - sqlite3_step(stmt); - sqlite3_reset(stmt); + try (sqlite3 db = createNewDb()){ + execSql(db, "CREATE TABLE t(a)"); + sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); + long total1 = 0; + for(long i = 0xffffffff; i < 0xffffffff + 3; ++i ){ + total1 += i; + sqlite3_bind_int64(stmt, 1, i); + sqlite3_step(stmt); + sqlite3_reset(stmt); + } + sqlite3_finalize(stmt); + stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); + long total2 = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + total2 += sqlite3_column_int64(stmt, 0); + } + sqlite3_finalize(stmt); + affirm(total1 == total2); + //sqlite3_close_v2(db); } - sqlite3_finalize(stmt); - stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); - long total2 = 0; - while( SQLITE_ROW == sqlite3_step(stmt) ){ - total2 += sqlite3_column_int64(stmt, 0); - } - sqlite3_finalize(stmt); - affirm(total1 == total2); - sqlite3_close_v2(db); } private void testBindFetchDouble(){ - sqlite3 db = createNewDb(); - execSql(db, "CREATE TABLE t(a)"); - sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); - double total1 = 0; - for(double i = 1.5; i < 5.0; i = i + 1.0 ){ - total1 += i; - sqlite3_bind_double(stmt, 1, i); - sqlite3_step(stmt); - sqlite3_reset(stmt); + try (sqlite3 db = createNewDb()){ + execSql(db, "CREATE TABLE t(a)"); + sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); + double total1 = 0; + for(double i = 1.5; i < 5.0; i = i + 1.0 ){ + total1 += i; + sqlite3_bind_double(stmt, 1, i); + sqlite3_step(stmt); + sqlite3_reset(stmt); + } + sqlite3_finalize(stmt); + stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); + double total2 = 0; + int counter = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + ++counter; + total2 += sqlite3_column_double(stmt, 0); + } + affirm(4 == counter); + sqlite3_finalize(stmt); + affirm(total2<=total1+0.01 && total2>=total1-0.01); + //sqlite3_close_v2(db); } - sqlite3_finalize(stmt); - stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); - double total2 = 0; - int counter = 0; - while( SQLITE_ROW == sqlite3_step(stmt) ){ - ++counter; - total2 += sqlite3_column_double(stmt, 0); - } - affirm(4 == counter); - sqlite3_finalize(stmt); - affirm(total2<=total1+0.01 && total2>=total1-0.01); - sqlite3_close_v2(db); } private void testBindFetchText(){ @@ -491,20 +498,25 @@ public class Tester1 implements Runnable { affirm(3 == n); affirm("w😃rldhell🤩!🤩".equals(sbuf.toString())); - stmt = prepare(db, "SELECT ?, ?"); - rc = sqlite3_bind_text(stmt, 1, ""); - affirm( 0==rc ); - rc = sqlite3_bind_text(stmt, 2, (String)null); - affirm( 0==rc ); - rc = sqlite3_step(stmt); - affirm( SQLITE_ROW==rc ); - byte[] colBa = sqlite3_column_text(stmt, 0); - affirm( 0==colBa.length ); - colBa = sqlite3_column_text(stmt, 1); - affirm( null==colBa ); - sqlite3_finalize(stmt); + try( sqlite3_stmt stmt2 = prepare(db, "SELECT ?, ?") ){ + rc = sqlite3_bind_text(stmt2, 1, ""); + affirm( 0==rc ); + rc = sqlite3_bind_text(stmt2, 2, (String)null); + affirm( 0==rc ); + rc = sqlite3_step(stmt2); + affirm( SQLITE_ROW==rc ); + byte[] colBa = sqlite3_column_text(stmt2, 0); + affirm( 0==colBa.length ); + colBa = sqlite3_column_text(stmt2, 1); + affirm( null==colBa ); + //sqlite3_finalize(stmt); + } - sqlite3_close_v2(db); + if(true){ + sqlite3_close_v2(db); + }else{ + // Let the Object.finalize() override deal with it. + } } private void testBindFetchBlob(){ @@ -543,7 +555,10 @@ public class Tester1 implements Runnable { sqlite3_finalize(stmt); stmt = prepare(db, "SELECT ?"); sqlite3_bind_text(stmt, 1, "hell😃"); - affirm( "SELECT 'hell😃'".equals(sqlite3_expanded_sql(stmt)) ); + final String expect = "SELECT 'hell😃'"; + affirm( expect.equals(sqlite3_expanded_sql(stmt)) ); + String n = sqlite3_normalized_sql(stmt); + affirm( null==n || "SELECT?;".equals(n) ); sqlite3_finalize(stmt); sqlite3_close(db); } @@ -668,6 +683,8 @@ public class Tester1 implements Runnable { // These ValueHolders are just to confirm that the func did what we want... final ValueHolder xDestroyCalled = new ValueHolder<>(false); final ValueHolder xFuncAccum = new ValueHolder<>(0); + final ValueHolder neverEverDoThisInClientCode = new ValueHolder<>(null); + final ValueHolder neverEverDoThisInClientCode2 = new ValueHolder<>(null); // Create an SQLFunction instance using one of its 3 subclasses: // Scalar, Aggregate, or Window: @@ -678,6 +695,15 @@ public class Tester1 implements Runnable { new ScalarFunction(){ public void xFunc(sqlite3_context cx, sqlite3_value[] args){ affirm(db == sqlite3_context_db_handle(cx)); + if( null==neverEverDoThisInClientCode.value ){ + /* !!!NEVER!!! hold a reference to an sqlite3_value or + sqlite3_context object like this in client code! They + are ONLY legal for the duration of their single + call. We do it here ONLY to test that the defenses + against clients doing this are working. */ + neverEverDoThisInClientCode2.value = cx; + neverEverDoThisInClientCode.value = args; + } int result = 0; for( sqlite3_value v : args ) result += sqlite3_value_int(v); xFuncAccum.value += result;// just for post-run testing @@ -703,6 +729,13 @@ public class Tester1 implements Runnable { affirm(1 == n); affirm(6 == xFuncAccum.value); affirm( !xDestroyCalled.value ); + affirm( null!=neverEverDoThisInClientCode.value ); + affirm( null!=neverEverDoThisInClientCode2.value ); + affirm( 0 0 ); + affirm( sqlite3_errmsg(db).indexOf("an xFinal") > 0 ); SQLFunction funcSc = new ScalarFunction(){ @Override public void xFunc(sqlite3_context cx, sqlite3_value[] args){ @@ -743,7 +776,7 @@ public class Tester1 implements Runnable { rc = sqlite3_step(stmt); sqlite3_finalize(stmt); affirm( 0 != rc ); - affirm( sqlite3_errmsg16(db).indexOf("an xFunc") > 0 ); + affirm( sqlite3_errmsg(db).indexOf("an xFunc") > 0 ); rc = sqlite3_create_function(db, "mysca", 1, -1, funcSc); affirm( SQLITE_FORMAT==rc, "invalid encoding value." ); sqlite3_close_v2(db); @@ -914,7 +947,7 @@ public class Tester1 implements Runnable { private void listBoundMethods(){ if(false){ final java.lang.reflect.Field[] declaredFields = - SQLite3Jni.class.getDeclaredFields(); + CApi.class.getDeclaredFields(); outln("Bound constants:\n"); for(java.lang.reflect.Field field : declaredFields) { if(java.lang.reflect.Modifier.isStatic(field.getModifiers())) { @@ -923,7 +956,7 @@ public class Tester1 implements Runnable { } } final java.lang.reflect.Method[] declaredMethods = - SQLite3Jni.class.getDeclaredMethods(); + CApi.class.getDeclaredMethods(); final java.util.List funcList = new java.util.ArrayList<>(); for(java.lang.reflect.Method m : declaredMethods){ if((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0){ @@ -1008,8 +1041,11 @@ public class Tester1 implements Runnable { affirm( 0 == rc ); affirm( outDb.get() != db1 ); final sqlite3 db2 = outDb.get(); + + affirm( "main".equals( sqlite3_db_name(db1, 0) ) ); rc = sqlite3_db_config(db1, SQLITE_DBCONFIG_MAINDBNAME, "foo"); affirm( sqlite3_db_filename(db1, "foo").endsWith(dbName) ); + affirm( "foo".equals( sqlite3_db_name(db1, 0) ) ); final ValueHolder xBusyCalled = new ValueHolder<>(0); BusyHandlerCallback handler = new BusyHandlerCallback(){ @@ -1025,7 +1061,7 @@ public class Tester1 implements Runnable { execSql(db1, "BEGIN EXCLUSIVE"); rc = sqlite3_prepare_v2(db2, "SELECT * from t", outStmt); affirm( SQLITE_BUSY == rc); - assert( null == outStmt.get() ); + affirm( null == outStmt.get() ); affirm( 3 == xBusyCalled.value ); sqlite3_close_v2(db1); sqlite3_close_v2(db2); @@ -1436,7 +1472,7 @@ public class Tester1 implements Runnable { affirm( "noCase".equals(zCollSeq.value) ); affirm( "duck".equals(zDataType.value) ); - final TableColumnMetadata m = + TableColumnMetadata m = sqlite3_table_column_metadata(db, "main", "t", "a"); affirm( null != m ); affirm( bPrimaryKey.value == m.isPrimaryKey() ); @@ -1446,6 +1482,16 @@ public class Tester1 implements Runnable { affirm( zDataType.value.equals(m.getDataType()) ); affirm( null == sqlite3_table_column_metadata(db, "nope", "t", "a") ); + affirm( null == sqlite3_table_column_metadata(db, "main", "nope", "a") ); + + m = sqlite3_table_column_metadata(db, "main", "t", null) + /* Check only for existence of table */; + affirm( null != m ); + affirm( m.isPrimaryKey() ); + affirm( !m.isAutoincrement() ); + affirm( !m.isNotNull() ); + affirm( "BINARY".equalsIgnoreCase(m.getCollation()) ); + affirm( "INTEGER".equalsIgnoreCase(m.getDataType()) ); sqlite3_close_v2(db); } @@ -1508,35 +1554,34 @@ public class Tester1 implements Runnable { } private void testBackup(){ - final sqlite3 db1 = createNewDb(); - final sqlite3 db2 = createNewDb(); + final sqlite3 dbDest = createNewDb(); - execSql(db1, new String[]{ - "pragma page_size=512; VACUUM;", - "create table t(a);", - "insert into t(a) values(1),(2),(3);" - }); - affirm( null==sqlite3_backup_init(db1,"main",db1,"main") ); - final sqlite3_backup b = sqlite3_backup_init(db2,"main",db1,"main"); - affirm( null!=b ); - affirm( b.getNativePointer()!=0 ); - int rc; - while( SQLITE_DONE!=(rc = sqlite3_backup_step(b, 1)) ){ - affirm( 0==rc ); + try (sqlite3 dbSrc = createNewDb()) { + execSql(dbSrc, new String[]{ + "pragma page_size=512; VACUUM;", + "create table t(a);", + "insert into t(a) values(1),(2),(3);" + }); + affirm( null==sqlite3_backup_init(dbSrc,"main",dbSrc,"main") ); + try (sqlite3_backup b = sqlite3_backup_init(dbDest,"main",dbSrc,"main")) { + affirm( null!=b ); + affirm( b.getNativePointer()!=0 ); + int rc; + while( SQLITE_DONE!=(rc = sqlite3_backup_step(b, 1)) ){ + affirm( 0==rc ); + } + affirm( sqlite3_backup_pagecount(b) > 0 ); + rc = sqlite3_backup_finish(b); + affirm( 0==rc ); + affirm( b.getNativePointer()==0 ); + } } - affirm( sqlite3_backup_pagecount(b) > 0 ); - rc = sqlite3_backup_finish(b); - affirm( 0==rc ); - affirm( b.getNativePointer()==0 ); - sqlite3_close_v2(db1); - - final sqlite3_stmt stmt = prepare(db2,"SELECT sum(a) from t"); - sqlite3_step(stmt); - affirm( sqlite3_column_int(stmt,0) == 6 ); - - sqlite3_finalize(stmt); - sqlite3_close_v2(db2); + try (sqlite3_stmt stmt = prepare(dbDest,"SELECT sum(a) from t")) { + sqlite3_step(stmt); + affirm( sqlite3_column_int(stmt,0) == 6 ); + } + sqlite3_close_v2(dbDest); } private void testRandomness(){ @@ -1906,29 +1951,24 @@ public class Tester1 implements Runnable { sqlite3_shutdown(); int nMethods = 0; int nNatives = 0; - int nCanonical = 0; final java.lang.reflect.Method[] declaredMethods = - SQLite3Jni.class.getDeclaredMethods(); + CApi.class.getDeclaredMethods(); for(java.lang.reflect.Method m : declaredMethods){ final int mod = m.getModifiers(); if( 0!=(mod & java.lang.reflect.Modifier.STATIC) ){ final String name = m.getName(); if(name.startsWith("sqlite3_")){ ++nMethods; - if( m.isAnnotationPresent( org.sqlite.jni.annotation.Canonical.class ) ){ - ++nCanonical; - } if( 0!=(mod & java.lang.reflect.Modifier.NATIVE) ){ ++nNatives; } } } } - outln("\tSQLite3Jni.sqlite3_*() methods: "+ + outln("\tCApi.sqlite3_*() methods: "+ nMethods+" total, with "+ nNatives+" native, "+ - (nMethods - nNatives)+" Java, ", - nCanonical," @Canonical" + (nMethods - nNatives)+" Java" ); outln("\tTotal test time = " +(timeEnd - timeStart)+"ms"); diff --git a/ext/jni/src/org/sqlite/jni/TraceV2Callback.java b/ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java similarity index 95% rename from ext/jni/src/org/sqlite/jni/TraceV2Callback.java rename to ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java index 4e69bd8756..56465a2c0a 100644 --- a/ext/jni/src/org/sqlite/jni/TraceV2Callback.java +++ b/ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java @@ -11,11 +11,11 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; import org.sqlite.jni.annotation.Nullable; /** - Callback for use with {@link SQLite3Jni#sqlite3_trace_v2}. + Callback for use with {@link CApi#sqlite3_trace_v2}. */ public interface TraceV2Callback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/UpdateHookCallback.java b/ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java similarity index 88% rename from ext/jni/src/org/sqlite/jni/UpdateHookCallback.java rename to ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java index 4d6afb887f..33d72a5dd2 100644 --- a/ext/jni/src/org/sqlite/jni/UpdateHookCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java @@ -11,10 +11,10 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** - Callback for use with {@link SQLite3Jni#sqlite3_update_hook}. + Callback for use with {@link CApi#sqlite3_update_hook}. */ public interface UpdateHookCallback extends CallbackProxy { /** diff --git a/ext/jni/src/org/sqlite/jni/capi/ValueHolder.java b/ext/jni/src/org/sqlite/jni/capi/ValueHolder.java new file mode 100644 index 0000000000..b3f03ac867 --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/capi/ValueHolder.java @@ -0,0 +1,25 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains a set of tests for the sqlite3 JNI bindings. +*/ +package org.sqlite.jni.capi; + +/** + A helper class which simply holds a single value. Its primary use + is for communicating values out of anonymous classes, as doing so + requires a "final" reference. +*/ +public class ValueHolder { + public T value; + public ValueHolder(){} + public ValueHolder(T v){value = v;} +} diff --git a/ext/jni/src/org/sqlite/jni/WindowFunction.java b/ext/jni/src/org/sqlite/jni/capi/WindowFunction.java similarity index 97% rename from ext/jni/src/org/sqlite/jni/WindowFunction.java rename to ext/jni/src/org/sqlite/jni/capi/WindowFunction.java index 7f70177ac0..eaf1bb9a35 100644 --- a/ext/jni/src/org/sqlite/jni/WindowFunction.java +++ b/ext/jni/src/org/sqlite/jni/capi/WindowFunction.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** diff --git a/ext/jni/src/org/sqlite/jni/XDestroyCallback.java b/ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java similarity index 97% rename from ext/jni/src/org/sqlite/jni/XDestroyCallback.java rename to ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java index 4b547e6bc9..372e4ec8d0 100644 --- a/ext/jni/src/org/sqlite/jni/XDestroyCallback.java +++ b/ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file declares JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** Callback for a hook called by SQLite when certain client-provided diff --git a/ext/jni/src/org/sqlite/jni/package-info.java b/ext/jni/src/org/sqlite/jni/capi/package-info.java similarity index 98% rename from ext/jni/src/org/sqlite/jni/package-info.java rename to ext/jni/src/org/sqlite/jni/capi/package-info.java index 853d76fd73..127f380675 100644 --- a/ext/jni/src/org/sqlite/jni/package-info.java +++ b/ext/jni/src/org/sqlite/jni/capi/package-info.java @@ -2,7 +2,7 @@ This package houses a JNI binding to the SQLite3 C API.

The primary interfaces are in {@link - org.sqlite.jni.SQLite3Jni}.

+ org.sqlite.jni.capi.CApi}.

API Goals and Requirements

@@ -86,4 +86,4 @@ undefined behavior.

*/ -package org.sqlite.jni; +package org.sqlite.jni.capi; diff --git a/ext/jni/src/org/sqlite/jni/sqlite3.java b/ext/jni/src/org/sqlite/jni/capi/sqlite3.java similarity index 75% rename from ext/jni/src/org/sqlite/jni/sqlite3.java rename to ext/jni/src/org/sqlite/jni/capi/sqlite3.java index cfc6c08d47..901317f0ef 100644 --- a/ext/jni/src/org/sqlite/jni/sqlite3.java +++ b/ext/jni/src/org/sqlite/jni/capi/sqlite3.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** A wrapper for communicating C-level (sqlite3*) instances with @@ -19,19 +19,25 @@ package org.sqlite.jni; simply provide a type-safe way to communicate it between Java and C via JNI. */ -public final class sqlite3 extends NativePointerHolder { +public final class sqlite3 extends NativePointerHolder + implements AutoCloseable { + // Only invoked from JNI private sqlite3(){} public String toString(){ - long ptr = getNativePointer(); + final long ptr = getNativePointer(); if( 0==ptr ){ return sqlite3.class.getSimpleName()+"@null"; } - String fn = SQLite3Jni.sqlite3_db_filename(this, "main"); + final String fn = CApi.sqlite3_db_filename(this, "main"); return sqlite3.class.getSimpleName() +"@"+String.format("0x%08x",ptr) +"["+((null == fn) ? "" : fn)+"]" ; } + + @Override public void close(){ + CApi.sqlite3_close_v2(this.clearNativePointer()); + } } diff --git a/ext/jni/src/org/sqlite/jni/sqlite3_backup.java b/ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java similarity index 84% rename from ext/jni/src/org/sqlite/jni/sqlite3_backup.java rename to ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java index d8ba78aec8..0ef75c17eb 100644 --- a/ext/jni/src/org/sqlite/jni/sqlite3_backup.java +++ b/ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** A wrapper for passing C-level (sqlite3_backup*) instances around in @@ -19,7 +19,13 @@ package org.sqlite.jni; simply provide a type-safe way to communicate it between Java and C via JNI. */ -public final class sqlite3_backup extends NativePointerHolder { +public final class sqlite3_backup extends NativePointerHolder + implements AutoCloseable { // Only invoked from JNI. private sqlite3_backup(){} + + @Override public void close(){ + CApi.sqlite3_backup_finish(this); + } + } diff --git a/ext/jni/src/org/sqlite/jni/sqlite3_blob.java b/ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java similarity index 82% rename from ext/jni/src/org/sqlite/jni/sqlite3_blob.java rename to ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java index e512130256..1b96c18b06 100644 --- a/ext/jni/src/org/sqlite/jni/sqlite3_blob.java +++ b/ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** A wrapper for passing C-level (sqlite3_blob*) instances around in @@ -19,7 +19,13 @@ package org.sqlite.jni; simply provide a type-safe way to communicate it between Java and C via JNI. */ -public final class sqlite3_blob extends NativePointerHolder { +public final class sqlite3_blob extends NativePointerHolder + implements AutoCloseable { // Only invoked from JNI. private sqlite3_blob(){} + + @Override public void close(){ + CApi.sqlite3_blob_close(this.clearNativePointer()); + } + } diff --git a/ext/jni/src/org/sqlite/jni/sqlite3_context.java b/ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java similarity index 96% rename from ext/jni/src/org/sqlite/jni/sqlite3_context.java rename to ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java index b9f11d7336..82ec49af16 100644 --- a/ext/jni/src/org/sqlite/jni/sqlite3_context.java +++ b/ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** sqlite3_context instances are used in conjunction with user-defined @@ -71,7 +71,7 @@ public final class sqlite3_context extends NativePointerHolder */ public synchronized Long getAggregateContext(boolean initIfNeeded){ if( aggregateContext==null ){ - aggregateContext = SQLite3Jni.sqlite3_aggregate_context(this, initIfNeeded); + aggregateContext = CApi.sqlite3_aggregate_context(this, initIfNeeded); if( !initIfNeeded && null==aggregateContext ) aggregateContext = 0L; } return (null==aggregateContext || 0!=aggregateContext) ? aggregateContext : null; diff --git a/ext/jni/src/org/sqlite/jni/sqlite3_stmt.java b/ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java similarity index 83% rename from ext/jni/src/org/sqlite/jni/sqlite3_stmt.java rename to ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java index d672301378..3b8b71f8a5 100644 --- a/ext/jni/src/org/sqlite/jni/sqlite3_stmt.java +++ b/ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; /** A wrapper for communicating C-level (sqlite3_stmt*) instances with @@ -19,7 +19,12 @@ package org.sqlite.jni; simply provide a type-safe way to communicate it between Java and C via JNI. */ -public final class sqlite3_stmt extends NativePointerHolder { +public final class sqlite3_stmt extends NativePointerHolder + implements AutoCloseable { // Only invoked from JNI. private sqlite3_stmt(){} + + @Override public void close(){ + CApi.sqlite3_finalize(this.clearNativePointer()); + } } diff --git a/ext/jni/src/org/sqlite/jni/sqlite3_value.java b/ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java similarity index 95% rename from ext/jni/src/org/sqlite/jni/sqlite3_value.java rename to ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java index 2cfb32ff1a..a4772f0f63 100644 --- a/ext/jni/src/org/sqlite/jni/sqlite3_value.java +++ b/ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java @@ -11,7 +11,7 @@ ************************************************************************* ** This file is part of the JNI bindings for the sqlite3 C API. */ -package org.sqlite.jni; +package org.sqlite.jni.capi; public final class sqlite3_value extends NativePointerHolder { //! Invoked only from JNI. diff --git a/ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java b/ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java index a5b937ceb8..439b477910 100644 --- a/ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java +++ b/ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java @@ -12,7 +12,7 @@ ** This file is part of the JNI bindings for the sqlite3 C API. */ package org.sqlite.jni.fts5; -import org.sqlite.jni.*; +import org.sqlite.jni.capi.*; /** A wrapper for communicating C-level (Fts5Context*) instances with diff --git a/ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java b/ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java index ef7dcc0533..594f3eaad6 100644 --- a/ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java +++ b/ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java @@ -13,14 +13,10 @@ */ package org.sqlite.jni.fts5; import java.nio.charset.StandardCharsets; -import org.sqlite.jni.*; +import org.sqlite.jni.capi.*; import org.sqlite.jni.annotation.*; /** - ALMOST COMPLETELY UNTESTED. - - FAR FROM COMPLETE and the feasibility of binding this to Java - is still undetermined. This might be removed. */ public final class Fts5ExtensionApi extends NativePointerHolder { //! Only called from JNI @@ -37,67 +33,51 @@ public final class Fts5ExtensionApi extends NativePointerHolder { */ public static synchronized native fts5_api getInstanceForDb(@NotNull sqlite3 db); - @Canonical public synchronized native int xCreateFunction(@NotNull String name, @Nullable Object userData, @NotNull fts5_extension_function xFunction); diff --git a/ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java b/ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java index 7ed353ac0b..5e47633baa 100644 --- a/ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java +++ b/ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java @@ -12,8 +12,8 @@ ** This file is part of the JNI bindings for the sqlite3 C API. */ package org.sqlite.jni.fts5; -import org.sqlite.jni.sqlite3_context; -import org.sqlite.jni.sqlite3_value; +import org.sqlite.jni.capi.sqlite3_context; +import org.sqlite.jni.capi.sqlite3_value; /** JNI-level wrapper for C's fts5_extension_function type. diff --git a/ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java b/ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java index fc2055cecd..f4ada4dc30 100644 --- a/ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java +++ b/ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java @@ -12,12 +12,10 @@ ** This file is part of the JNI bindings for the sqlite3 C API. */ package org.sqlite.jni.fts5; -import org.sqlite.jni.NativePointerHolder; +import org.sqlite.jni.capi.NativePointerHolder; import org.sqlite.jni.annotation.NotNull; /** - INCOMPLETE AND COMPLETELY UNTESTED. - A wrapper for communicating C-level (fts5_tokenizer*) instances with Java. These wrappers do not own their associated pointer, they simply provide a type-safe way to communicate it between Java and C diff --git a/ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md b/ext/jni/src/org/sqlite/jni/test-script-interpreter.md similarity index 100% rename from ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md rename to ext/jni/src/org/sqlite/jni/test-script-interpreter.md diff --git a/ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java b/ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java new file mode 100644 index 0000000000..173d775e62 --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java @@ -0,0 +1,82 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import org.sqlite.jni.capi.CApi; +import org.sqlite.jni.annotation.*; +import org.sqlite.jni.capi.sqlite3_context; +import org.sqlite.jni.capi.sqlite3_value; + +/** + EXPERIMENTAL/INCOMPLETE/UNTESTED + + A SqlFunction implementation for aggregate functions. The T type + represents the type of data accumulated by this aggregate while it + works. e.g. a SUM()-like UDF might use Integer or Long and a + CONCAT()-like UDF might use a StringBuilder or a List. +*/ +public abstract class AggregateFunction implements SqlFunction { + + /** + As for the xStep() argument of the C API's + sqlite3_create_function(). If this function throws, the + exception is reported via sqlite3_result_error(). + */ + public abstract void xStep(SqlFunction.Arguments args); + + /** + As for the xFinal() argument of the C API's + sqlite3_create_function(). If this function throws, it is + translated into sqlite3_result_error(). + + Note that the passed-in object will not actually contain any + arguments for xFinal() but will contain the context object needed + for setting the call's result or error state. + */ + public abstract void xFinal(SqlFunction.Arguments args); + + /** + Optionally override to be notified when the UDF is finalized by + SQLite. + */ + public void xDestroy() {} + + /** Per-invocation state for the UDF. */ + private final SqlFunction.PerContextState map = + new SqlFunction.PerContextState<>(); + + /** + To be called from the implementation's xStep() method, as well + as the xValue() and xInverse() methods of the {@link WindowFunction} + subclass, to fetch the current per-call UDF state. On the + first call to this method for any given sqlite3_context + argument, the context is set to the given initial value. On all other + calls, the 2nd argument is ignored. + + @see SQLFunction.PerContextState#getAggregateState + */ + protected final ValueHolder getAggregateState(SqlFunction.Arguments args, T initialValue){ + return map.getAggregateState(args, initialValue); + } + + /** + To be called from the implementation's xFinal() method to fetch + the final state of the UDF and remove its mapping. + + see SQLFunction.PerContextState#takeAggregateState + */ + protected final T takeAggregateState(SqlFunction.Arguments args){ + return map.takeAggregateState(args); + } + +} diff --git a/ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java b/ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java new file mode 100644 index 0000000000..067a6983eb --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java @@ -0,0 +1,37 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import org.sqlite.jni.capi.CApi; +import org.sqlite.jni.annotation.*; +import org.sqlite.jni.capi.sqlite3_context; +import org.sqlite.jni.capi.sqlite3_value; + +/** + The SqlFunction type for scalar SQL functions. +*/ +public abstract class ScalarFunction implements SqlFunction { + /** + As for the xFunc() argument of the C API's + sqlite3_create_function(). If this function throws, it is + translated into an sqlite3_result_error(). + */ + public abstract void xFunc(SqlFunction.Arguments args); + + /** + Optionally override to be notified when the UDF is finalized by + SQLite. This default implementation does nothing. + */ + public void xDestroy() {} + +} diff --git a/ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java b/ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java new file mode 100644 index 0000000000..d6acda5aa5 --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java @@ -0,0 +1,301 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import org.sqlite.jni.capi.CApi; +import org.sqlite.jni.capi.sqlite3_context; +import org.sqlite.jni.capi.sqlite3_value; + +/** + Base marker interface for SQLite's three types of User-Defined SQL + Functions (UDFs): Scalar, Aggregate, and Window functions. +*/ +public interface SqlFunction { + + /** + The Arguments type is an abstraction on top of the lower-level + UDF function argument types. It provides _most_ of the functionality + of the lower-level interface, insofar as possible without "leaking" + those types into this API. + */ + public final static class Arguments implements Iterable{ + private final sqlite3_context cx; + private final sqlite3_value args[]; + public final int length; + + /** + Must be passed the context and arguments for the UDF call this + object is wrapping. Intended to be used by internal proxy + classes which "convert" the lower-level interface into this + package's higher-level interface, e.g. ScalarAdapter and + AggregateAdapter. + + Passing null for the args is equivalent to passing a length-0 + array. + */ + Arguments(sqlite3_context cx, sqlite3_value args[]){ + this.cx = cx; + this.args = args==null ? new sqlite3_value[0] : args;; + this.length = this.args.length; + } + + /** + Wrapper for a single SqlFunction argument. Primarily intended + for use with the Arguments class's Iterable interface. + */ + public final static class Arg { + private final Arguments a; + private final int ndx; + /* Only for use by the Arguments class. */ + private Arg(Arguments a, int ndx){ + this.a = a; + this.ndx = ndx; + } + /** Returns this argument's index in its parent argument list. */ + public int getIndex(){return ndx;} + public int getInt(){return a.getInt(ndx);} + public long getInt64(){return a.getInt64(ndx);} + public double getDouble(){return a.getDouble(ndx);} + public byte[] getBlob(){return a.getBlob(ndx);} + public byte[] getText(){return a.getText(ndx);} + public String getText16(){return a.getText16(ndx);} + public int getBytes(){return a.getBytes(ndx);} + public int getBytes16(){return a.getBytes16(ndx);} + public Object getObject(){return a.getObject(ndx);} + public T getObjectCasted(Class type){ return a.getObjectCasted(ndx, type); } + public int getType(){return a.getType(ndx);} + public Object getAuxData(){return a.getAuxData(ndx);} + public void setAuxData(Object o){a.setAuxData(ndx, o);} + } + + @Override + public java.util.Iterator iterator(){ + final Arg[] proxies = new Arg[args.length]; + for( int i = 0; i < args.length; ++i ){ + proxies[i] = new Arg(this, i); + } + return java.util.Arrays.stream(proxies).iterator(); + } + + /** + Returns the sqlite3_value at the given argument index or throws + an IllegalArgumentException exception if ndx is out of range. + */ + private sqlite3_value valueAt(int ndx){ + if(ndx<0 || ndx>=args.length){ + throw new IllegalArgumentException( + "SQL function argument index "+ndx+" is out of range." + ); + } + return args[ndx]; + } + + sqlite3_context getContext(){return cx;} + + public int getArgCount(){ return args.length; } + + public int getInt(int arg){return CApi.sqlite3_value_int(valueAt(arg));} + public long getInt64(int arg){return CApi.sqlite3_value_int64(valueAt(arg));} + public double getDouble(int arg){return CApi.sqlite3_value_double(valueAt(arg));} + public byte[] getBlob(int arg){return CApi.sqlite3_value_blob(valueAt(arg));} + public byte[] getText(int arg){return CApi.sqlite3_value_text(valueAt(arg));} + public String getText16(int arg){return CApi.sqlite3_value_text16(valueAt(arg));} + public int getBytes(int arg){return CApi.sqlite3_value_bytes(valueAt(arg));} + public int getBytes16(int arg){return CApi.sqlite3_value_bytes16(valueAt(arg));} + public Object getObject(int arg){return CApi.sqlite3_value_java_object(valueAt(arg));} + public T getObjectCasted(int arg, Class type){ + return CApi.sqlite3_value_java_casted(valueAt(arg), type); + } + + public int getType(int arg){return CApi.sqlite3_value_type(valueAt(arg));} + public int getSubtype(int arg){return CApi.sqlite3_value_subtype(valueAt(arg));} + public int getNumericType(int arg){return CApi.sqlite3_value_numeric_type(valueAt(arg));} + public int getNoChange(int arg){return CApi.sqlite3_value_nochange(valueAt(arg));} + public boolean getFromBind(int arg){return CApi.sqlite3_value_frombind(valueAt(arg));} + public int getEncoding(int arg){return CApi.sqlite3_value_encoding(valueAt(arg));} + + public void resultInt(int v){ CApi.sqlite3_result_int(cx, v); } + public void resultInt64(long v){ CApi.sqlite3_result_int64(cx, v); } + public void resultDouble(double v){ CApi.sqlite3_result_double(cx, v); } + public void resultError(String msg){CApi.sqlite3_result_error(cx, msg);} + public void resultError(Exception e){CApi.sqlite3_result_error(cx, e);} + public void resultErrorTooBig(){CApi.sqlite3_result_error_toobig(cx);} + public void resultErrorCode(int rc){CApi.sqlite3_result_error_code(cx, rc);} + public void resultObject(Object o){CApi.sqlite3_result_java_object(cx, o);} + public void resultNull(){CApi.sqlite3_result_null(cx);} + public void resultArg(int argNdx){CApi.sqlite3_result_value(cx, valueAt(argNdx));} + public void resultZeroBlob(long n){ + // Throw on error? If n is too big, + // sqlite3_result_error_toobig() is automatically called. + CApi.sqlite3_result_zeroblob64(cx, n); + } + + public void resultBlob(byte[] blob){CApi.sqlite3_result_blob(cx, blob);} + public void resultText(byte[] utf8){CApi.sqlite3_result_text(cx, utf8);} + public void resultText(String txt){CApi.sqlite3_result_text(cx, txt);} + public void resultText16(byte[] utf16){CApi.sqlite3_result_text16(cx, utf16);} + public void resultText16(String txt){CApi.sqlite3_result_text16(cx, txt);} + + public void setAuxData(int arg, Object o){ + /* From the API docs: https://www.sqlite.org/c3ref/get_auxdata.html + + The value of the N parameter to these interfaces should be + non-negative. Future enhancements may make use of negative N + values to define new kinds of function caching behavior. + */ + valueAt(arg); + CApi.sqlite3_set_auxdata(cx, arg, o); + } + + public Object getAuxData(int arg){ + valueAt(arg); + return CApi.sqlite3_get_auxdata(cx, arg); + } + } + + /** + PerContextState assists aggregate and window functions in + managing their accumulator state across calls to the UDF's + callbacks. + +

T must be of a type which can be legally stored as a value in + java.util.HashMap. + +

If a given aggregate or window function is called multiple times + in a single SQL statement, e.g. SELECT MYFUNC(A), MYFUNC(B)..., + then the clients need some way of knowing which call is which so + that they can map their state between their various UDF callbacks + and reset it via xFinal(). This class takes care of such + mappings. + +

This class works by mapping + sqlite3_context.getAggregateContext() to a single piece of + state, of a client-defined type (the T part of this class), which + persists across a "matching set" of the UDF's callbacks. + +

This class is a helper providing commonly-needed functionality + - it is not required for use with aggregate or window functions. + Client UDFs are free to perform such mappings using custom + approaches. The provided {@link AggregateFunction} and {@link + WindowFunction} classes use this. + */ + public static final class PerContextState { + private final java.util.Map> map + = new java.util.HashMap<>(); + + /** + Should be called from a UDF's xStep(), xValue(), and xInverse() + methods, passing it that method's first argument and an initial + value for the persistent state. If there is currently no + mapping for the given context within the map, one is created + using the given initial value, else the existing one is used + and the 2nd argument is ignored. It returns a ValueHolder + which can be used to modify that state directly without + requiring that the client update the underlying map's entry. + +

The caller is obligated to eventually call + takeAggregateState() to clear the mapping. + */ + public ValueHolder getAggregateState(SqlFunction.Arguments args, T initialValue){ + final Long key = args.getContext().getAggregateContext(true); + ValueHolder rc = null==key ? null : map.get(key); + if( null==rc ){ + map.put(key, rc = new ValueHolder<>(initialValue)); + } + return rc; + } + + /** + Should be called from a UDF's xFinal() method and passed that + method's first argument. This function removes the value + associated with with the arguments' aggregate context from the + map and returns it, returning null if no other UDF method has + been called to set up such a mapping. The latter condition will + be the case if a UDF is used in a statement which has no result + rows. + */ + public T takeAggregateState(SqlFunction.Arguments args){ + final ValueHolder h = map.remove(args.getContext().getAggregateContext(false)); + return null==h ? null : h.value; + } + } + + /** + Internal-use adapter for wrapping this package's ScalarFunction + for use with the org.sqlite.jni.capi.ScalarFunction interface. + */ + static final class ScalarAdapter extends org.sqlite.jni.capi.ScalarFunction { + final ScalarFunction impl; + ScalarAdapter(ScalarFunction impl){ + this.impl = impl; + } + /** + Proxies this.impl.xFunc(), adapting the call arguments to that + function's signature. If the proxy throws, it's translated to + sqlite_result_error() with the exception's message. + */ + public void xFunc(sqlite3_context cx, sqlite3_value[] args){ + try{ + impl.xFunc( new SqlFunction.Arguments(cx, args) ); + }catch(Exception e){ + CApi.sqlite3_result_error(cx, e); + } + } + + public void xDestroy(){ + impl.xDestroy(); + } + } + + /** + Internal-use adapter for wrapping this package's AggregateFunction + for use with the org.sqlite.jni.capi.AggregateFunction interface. + */ + static final class AggregateAdapter extends org.sqlite.jni.capi.AggregateFunction { + final AggregateFunction impl; + AggregateAdapter(AggregateFunction impl){ + this.impl = impl; + } + + /** + Proxies this.impl.xStep(), adapting the call arguments to that + function's signature. If the proxied function throws, it is + translated to sqlite_result_error() with the exception's + message. + */ + public void xStep(sqlite3_context cx, sqlite3_value[] args){ + try{ + impl.xStep( new SqlFunction.Arguments(cx, args) ); + }catch(Exception e){ + CApi.sqlite3_result_error(cx, e); + } + } + + /** + As for the xFinal() argument of the C API's sqlite3_create_function(). + If the proxied function throws, it is translated into a sqlite3_result_error(). + */ + public void xFinal(sqlite3_context cx){ + try{ + impl.xFinal( new SqlFunction.Arguments(cx, null) ); + }catch(Exception e){ + CApi.sqlite3_result_error(cx, e); + } + } + + public void xDestroy(){ + impl.xDestroy(); + } + } + +} diff --git a/ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java b/ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java new file mode 100644 index 0000000000..bcf97b2394 --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java @@ -0,0 +1,218 @@ +/* +** 2023-10-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import java.nio.charset.StandardCharsets; +import static org.sqlite.jni.capi.CApi.*; +import org.sqlite.jni.capi.CApi; +import org.sqlite.jni.capi.sqlite3; +import org.sqlite.jni.capi.sqlite3_stmt; +import org.sqlite.jni.capi.OutputPointer; + +/** + This class represents a database connection, analog to the C-side + sqlite3 class but with added argument validation, exceptions, and + similar "smoothing of sharp edges" to make the API safe to use from + Java. It also acts as a namespace for other types for which + individual instances are tied to a specific database connection. +*/ +public final class Sqlite implements AutoCloseable { + private sqlite3 db; + + //! Used only by the open() factory functions. + private Sqlite(sqlite3 db){ + this.db = db; + } + + /** + Returns a newly-opened db connection or throws SqliteException if + opening fails. All arguments are as documented for + sqlite3_open_v2(). + + Design question: do we want static factory functions or should + this be reformulated as a constructor? + */ + public static Sqlite open(String filename, int flags, String vfsName){ + final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); + final int rc = sqlite3_open_v2(filename, out, flags, vfsName); + final sqlite3 n = out.take(); + if( 0!=rc ){ + if( null==n ) throw new SqliteException(rc); + final SqliteException ex = new SqliteException(n); + n.close(); + throw ex; + } + return new Sqlite(n); + } + + public static Sqlite open(String filename, int flags){ + return open(filename, flags, null); + } + + public static Sqlite open(String filename){ + return open(filename, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, null); + } + + @Override public void close(){ + if(null!=this.db){ + this.db.close(); + this.db = null; + } + } + + /** + Returns this object's underlying native db handle, or null if + this instance has been closed. This is very specifically not + public. + */ + sqlite3 nativeHandle(){ return this.db; } + + private sqlite3 affirmOpen(){ + if( null==db || 0==db.getNativePointer() ){ + throw new IllegalArgumentException("This database instance is closed."); + } + return this.db; + } + + // private byte[] stringToUtf8(String s){ + // return s==null ? null : s.getBytes(StandardCharsets.UTF_8); + // } + + private void affirmRcOk(int rc){ + if( 0!=rc ){ + throw new SqliteException(db); + } + } + + /** + Corresponds to the sqlite3_stmt class. Use Sqlite.prepare() to + create new instances. + */ + public final class Stmt implements AutoCloseable { + private Sqlite _db = null; + private sqlite3_stmt stmt = null; + /** Only called by the prepare() factory functions. */ + Stmt(Sqlite db, sqlite3_stmt stmt){ + this._db = db; + this.stmt = stmt; + } + + sqlite3_stmt nativeHandle(){ + return stmt; + } + + private sqlite3_stmt affirmOpen(){ + if( null==stmt || 0==stmt.getNativePointer() ){ + throw new IllegalArgumentException("This Stmt has been finalized."); + } + return stmt; + } + + /** + Corresponds to sqlite3_finalize(), but we cannot override the + name finalize() here because this one requires a different + signature. It does not throw on error here because "destructors + do not throw." If it returns non-0, the object is still + finalized. + */ + public int finalizeStmt(){ + int rc = 0; + if( null!=stmt ){ + sqlite3_finalize(stmt); + stmt = null; + } + return rc; + } + + @Override public void close(){ + finalizeStmt(); + } + + /** + Throws if rc is any value other than 0, SQLITE_ROW, or + SQLITE_DONE, else returns rc. + */ + private int checkRc(int rc){ + switch(rc){ + case 0: + case SQLITE_ROW: + case SQLITE_DONE: return rc; + default: + throw new SqliteException(this); + } + } + + /** + Works like sqlite3_step() but throws SqliteException for any + result other than 0, SQLITE_ROW, or SQLITE_DONE. + */ + public int step(){ + return checkRc(sqlite3_step(affirmOpen())); + } + + public Sqlite db(){ return this._db; } + + /** + Works like sqlite3_reset() but throws on error. + */ + public void reset(){ + checkRc(sqlite3_reset(affirmOpen())); + } + + public void clearBindings(){ + sqlite3_clear_bindings( affirmOpen() ); + } + } + + + /** + prepare() TODOs include: + + - overloads taking byte[] and ByteBuffer. + + - multi-statement processing, like CApi.sqlite3_prepare_multi() + but using a callback specific to the higher-level Stmt class + rather than the sqlite3_stmt class. + */ + public Stmt prepare(String sql, int prepFlags){ + final OutputPointer.sqlite3_stmt out = new OutputPointer.sqlite3_stmt(); + final int rc = sqlite3_prepare_v3(affirmOpen(), sql, prepFlags, out); + affirmRcOk(rc); + return new Stmt(this, out.take()); + } + + public Stmt prepare(String sql){ + return prepare(sql, 0); + } + + public void createFunction(String name, int nArg, int eTextRep, ScalarFunction f ){ + int rc = CApi.sqlite3_create_function(affirmOpen(), name, nArg, eTextRep, + new SqlFunction.ScalarAdapter(f)); + if( 0!=rc ) throw new SqliteException(db); + } + + public void createFunction(String name, int nArg, ScalarFunction f){ + this.createFunction(name, nArg, CApi.SQLITE_UTF8, f); + } + + public void createFunction(String name, int nArg, int eTextRep, AggregateFunction f ){ + int rc = CApi.sqlite3_create_function(affirmOpen(), name, nArg, eTextRep, + new SqlFunction.AggregateAdapter(f)); + if( 0!=rc ) throw new SqliteException(db); + } + + public void createFunction(String name, int nArg, AggregateFunction f){ + this.createFunction(name, nArg, CApi.SQLITE_UTF8, f); + } + +} diff --git a/ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java b/ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java new file mode 100644 index 0000000000..111f004db4 --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java @@ -0,0 +1,82 @@ +/* +** 2023-10-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import static org.sqlite.jni.capi.CApi.*; +import org.sqlite.jni.capi.sqlite3; + +/** + A wrapper for communicating C-level (sqlite3*) instances with + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java + and C via JNI. +*/ +public final class SqliteException extends java.lang.RuntimeException { + int errCode = SQLITE_ERROR; + int xerrCode = SQLITE_ERROR; + int errOffset = -1; + int sysErrno = 0; + + /** + Records the given error string and uses SQLITE_ERROR for both the + error code and extended error code. + */ + public SqliteException(String msg){ + super(msg); + } + + /** + Uses sqlite3_errstr(sqlite3ResultCode) for the error string and + sets both the error code and extended error code to the given + value. + */ + public SqliteException(int sqlite3ResultCode){ + super(sqlite3_errstr(sqlite3ResultCode)); + errCode = xerrCode = sqlite3ResultCode; + } + + /** + Records the current error state of db (which must not be null and + must refer to an opened db object). Note that this does NOT close + the db. + + Design note: closing the db on error is likely only useful during + a failed db-open operation, and the place(s) where that can + happen are inside this library, not client-level code. + */ + SqliteException(sqlite3 db){ + super(sqlite3_errmsg(db)); + errCode = sqlite3_errcode(db); + xerrCode = sqlite3_extended_errcode(db); + errOffset = sqlite3_error_offset(db); + sysErrno = sqlite3_system_errno(db); + } + + /** + Records the current error state of db (which must not be null and + must refer to an open database). + */ + public SqliteException(Sqlite db){ + this(db.nativeHandle()); + } + + public SqliteException(Sqlite.Stmt stmt){ + this( stmt.db() ); + } + + public int errcode(){ return errCode; } + public int extendedErrcode(){ return xerrCode; } + public int errorOffset(){ return errOffset; } + public int systemErrno(){ return sysErrno; } + +} diff --git a/ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java b/ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java new file mode 100644 index 0000000000..f5fd5f84e6 --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java @@ -0,0 +1,584 @@ +/* +** 2023-10-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains a set of tests for the sqlite3 JNI bindings. +*/ +package org.sqlite.jni.wrapper1; +//import static org.sqlite.jni.capi.CApi.*; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.sqlite.jni.capi.*; + +/** + An annotation for Tester2 tests which we do not want to run in + reflection-driven test mode because either they are not suitable + for multi-threaded threaded mode or we have to control their execution + order. +*/ +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) +@interface ManualTest{} +/** + Annotation for Tester2 tests which mark those which must be skipped + in multi-threaded mode. +*/ +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) +@interface SingleThreadOnly{} + +public class Tester2 implements Runnable { + //! True when running in multi-threaded mode. + private static boolean mtMode = false; + //! True to sleep briefly between tests. + private static boolean takeNaps = false; + //! True to shuffle the order of the tests. + private static boolean shuffle = false; + //! True to dump the list of to-run tests to stdout. + private static boolean listRunTests = false; + //! True to squelch all out() and outln() output. + private static boolean quietMode = false; + //! Total number of runTests() calls. + private static int nTestRuns = 0; + //! List of test*() methods to run. + private static List testMethods = null; + //! List of exceptions collected by run() + private static List listErrors = new ArrayList<>(); + private static final class Metrics { + //! Number of times createNewDb() (or equivalent) is invoked. + volatile int dbOpen = 0; + } + + //! Instance ID. + private Integer tId; + + Tester2(Integer id){ + tId = id; + } + + static final Metrics metrics = new Metrics(); + + public static synchronized void outln(){ + if( !quietMode ){ + System.out.println(""); + } + } + + public static synchronized void outPrefix(){ + if( !quietMode ){ + System.out.print(Thread.currentThread().getName()+": "); + } + } + + public static synchronized void outln(Object val){ + if( !quietMode ){ + outPrefix(); + System.out.println(val); + } + } + + public static synchronized void out(Object val){ + if( !quietMode ){ + System.out.print(val); + } + } + + @SuppressWarnings("unchecked") + public static synchronized void out(Object... vals){ + if( !quietMode ){ + outPrefix(); + for(Object v : vals) out(v); + } + } + + @SuppressWarnings("unchecked") + public static synchronized void outln(Object... vals){ + if( !quietMode ){ + out(vals); out("\n"); + } + } + + static volatile int affirmCount = 0; + public static synchronized int affirm(Boolean v, String comment){ + ++affirmCount; + if( false ) assert( v /* prefer assert over exception if it's enabled because + the JNI layer sometimes has to suppress exceptions, + so they might be squelched on their way back to the + top. */); + if( !v ) throw new RuntimeException(comment); + return affirmCount; + } + + public static void affirm(Boolean v){ + affirm(v, "Affirmation failed."); + } + + + public static void execSql(Sqlite db, String[] sql){ + execSql(db, String.join("", sql)); + } + + public static int execSql(Sqlite dbw, boolean throwOnError, String sql){ + final sqlite3 db = dbw.nativeHandle(); + OutputPointer.Int32 oTail = new OutputPointer.Int32(); + final byte[] sqlUtf8 = sql.getBytes(StandardCharsets.UTF_8); + int pos = 0, n = 1; + byte[] sqlChunk = sqlUtf8; + int rc = 0; + sqlite3_stmt stmt = null; + final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); + while(pos < sqlChunk.length){ + if(pos > 0){ + sqlChunk = Arrays.copyOfRange(sqlChunk, pos, + sqlChunk.length); + } + if( 0==sqlChunk.length ) break; + rc = CApi.sqlite3_prepare_v2(db, sqlChunk, outStmt, oTail); + if(throwOnError) affirm(0 == rc); + else if( 0!=rc ) break; + pos = oTail.value; + stmt = outStmt.take(); + if( null == stmt ){ + // empty statement was parsed. + continue; + } + affirm(0 != stmt.getNativePointer()); + while( CApi.SQLITE_ROW == (rc = CApi.sqlite3_step(stmt)) ){ + } + CApi.sqlite3_finalize(stmt); + affirm(0 == stmt.getNativePointer()); + if(0!=rc && CApi.SQLITE_ROW!=rc && CApi.SQLITE_DONE!=rc){ + break; + } + } + CApi.sqlite3_finalize(stmt); + if(CApi.SQLITE_ROW==rc || CApi.SQLITE_DONE==rc) rc = 0; + if( 0!=rc && throwOnError){ + throw new SqliteException(db); + } + return rc; + } + + static void execSql(Sqlite db, String sql){ + execSql(db, true, sql); + } + + @SingleThreadOnly /* because it's thread-agnostic */ + private void test1(){ + affirm(CApi.sqlite3_libversion_number() == CApi.SQLITE_VERSION_NUMBER); + } + + /* Copy/paste/rename this to add new tests. */ + private void _testTemplate(){ + //final sqlite3 db = createNewDb(); + //sqlite3_stmt stmt = prepare(db,"SELECT 1"); + //sqlite3_finalize(stmt); + //sqlite3_close_v2(db); + } + + private void nap() throws InterruptedException { + if( takeNaps ){ + Thread.sleep(java.util.concurrent.ThreadLocalRandom.current().nextInt(3, 17), 0); + } + } + + Sqlite openDb(String name){ + final Sqlite db = Sqlite.open(name, CApi.SQLITE_OPEN_READWRITE| + CApi.SQLITE_OPEN_CREATE| + CApi.SQLITE_OPEN_EXRESCODE); + ++metrics.dbOpen; + return db; + } + + Sqlite openDb(){ return openDb(":memory:"); } + + void testOpenDb1(){ + Sqlite db = openDb(); + affirm( 0!=db.nativeHandle().getNativePointer() ); + db.close(); + affirm( null==db.nativeHandle() ); + + SqliteException ex = null; + try { + db = openDb("/no/such/dir/.../probably"); + }catch(SqliteException e){ + ex = e; + } + affirm( ex!=null ); + affirm( ex.errcode() != 0 ); + affirm( ex.extendedErrcode() != 0 ); + affirm( ex.errorOffset() < 0 ); + // there's no reliable way to predict what ex.systemErrno() might be + } + + void testPrepare1(){ + try (Sqlite db = openDb()) { + Sqlite.Stmt stmt = db.prepare("SELECT 1"); + affirm( null!=stmt.nativeHandle() ); + affirm( CApi.SQLITE_ROW == stmt.step() ); + affirm( CApi.SQLITE_DONE == stmt.step() ); + stmt.reset(); + affirm( CApi.SQLITE_ROW == stmt.step() ); + affirm( CApi.SQLITE_DONE == stmt.step() ); + affirm( 0 == stmt.finalizeStmt() ); + affirm( null==stmt.nativeHandle() ); + + stmt = db.prepare("SELECT 1"); + affirm( CApi.SQLITE_ROW == stmt.step() ); + affirm( 0 == stmt.finalizeStmt() ) + /* getting a non-0 out of sqlite3_finalize() is tricky */; + affirm( null==stmt.nativeHandle() ); + } + } + + void testUdfScalar(){ + final ValueHolder xDestroyCalled = new ValueHolder<>(0); + try (Sqlite db = openDb()) { + execSql(db, "create table t(a); insert into t(a) values(1),(2),(3)"); + final ValueHolder vh = new ValueHolder<>(0); + final ScalarFunction f = new ScalarFunction(){ + public void xFunc(SqlFunction.Arguments args){ + for( SqlFunction.Arguments.Arg arg : args ){ + vh.value += arg.getInt(); + } + } + public void xDestroy(){ + ++xDestroyCalled.value; + } + }; + db.createFunction("myfunc", -1, f); + execSql(db, "select myfunc(1,2,3)"); + affirm( 6 == vh.value ); + vh.value = 0; + execSql(db, "select myfunc(-1,-2,-3)"); + affirm( -6 == vh.value ); + affirm( 0 == xDestroyCalled.value ); + } + affirm( 1 == xDestroyCalled.value ); + } + + void testUdfAggregate(){ + final ValueHolder xDestroyCalled = new ValueHolder<>(0); + final ValueHolder vh = new ValueHolder<>(0); + try (Sqlite db = openDb()) { + execSql(db, "create table t(a); insert into t(a) values(1),(2),(3)"); + final AggregateFunction f = new AggregateFunction(){ + public void xStep(SqlFunction.Arguments args){ + final ValueHolder agg = this.getAggregateState(args, 0); + for( SqlFunction.Arguments.Arg arg : args ){ + agg.value += arg.getInt(); + } + } + public void xFinal(SqlFunction.Arguments args){ + final Integer v = this.takeAggregateState(args); + if( null==v ) args.resultNull(); + else args.resultInt(v); + vh.value = v; + } + public void xDestroy(){ + ++xDestroyCalled.value; + } + }; + db.createFunction("myagg", -1, f); + execSql(db, "select myagg(a) from t"); + affirm( 6 == vh.value ); + affirm( 0 == xDestroyCalled.value ); + } + affirm( 1 == xDestroyCalled.value ); + } + + private void runTests(boolean fromThread) throws Exception { + List mlist = testMethods; + affirm( null!=mlist ); + if( shuffle ){ + mlist = new ArrayList<>( testMethods.subList(0, testMethods.size()) ); + java.util.Collections.shuffle(mlist); + } + if( listRunTests ){ + synchronized(this.getClass()){ + if( !fromThread ){ + out("Initial test"," list: "); + for(java.lang.reflect.Method m : testMethods){ + out(m.getName()+" "); + } + outln(); + outln("(That list excludes some which are hard-coded to run.)"); + } + out("Running"," tests: "); + for(java.lang.reflect.Method m : mlist){ + out(m.getName()+" "); + } + outln(); + } + } + for(java.lang.reflect.Method m : mlist){ + nap(); + try{ + m.invoke(this); + }catch(java.lang.reflect.InvocationTargetException e){ + outln("FAILURE: ",m.getName(),"(): ", e.getCause()); + throw e; + } + } + synchronized( this.getClass() ){ + ++nTestRuns; + } + } + + public void run() { + try { + runTests(0!=this.tId); + }catch(Exception e){ + synchronized( listErrors ){ + listErrors.add(e); + } + }finally{ + affirm( CApi.sqlite3_java_uncache_thread() ); + affirm( !CApi.sqlite3_java_uncache_thread() ); + } + } + + /** + Runs the basic sqlite3 JNI binding sanity-check suite. + + CLI flags: + + -q|-quiet: disables most test output. + + -t|-thread N: runs the tests in N threads + concurrently. Default=1. + + -r|-repeat N: repeats the tests in a loop N times, each one + consisting of the -thread value's threads. + + -shuffle: randomizes the order of most of the test functions. + + -naps: sleep small random intervals between tests in order to add + some chaos for cross-thread contention. + + -list-tests: outputs the list of tests being run, minus some + which are hard-coded. This is noisy in multi-threaded mode. + + -fail: forces an exception to be thrown during the test run. Use + with -shuffle to make its appearance unpredictable. + + -v: emit some developer-mode info at the end. + */ + public static void main(String[] args) throws Exception { + Integer nThread = 1; + boolean doSomethingForDev = false; + Integer nRepeat = 1; + boolean forceFail = false; + boolean sqlLog = false; + boolean configLog = false; + boolean squelchTestOutput = false; + for( int i = 0; i < args.length; ){ + String arg = args[i++]; + if(arg.startsWith("-")){ + arg = arg.replaceFirst("-+",""); + if(arg.equals("v")){ + doSomethingForDev = true; + //listBoundMethods(); + }else if(arg.equals("t") || arg.equals("thread")){ + nThread = Integer.parseInt(args[i++]); + }else if(arg.equals("r") || arg.equals("repeat")){ + nRepeat = Integer.parseInt(args[i++]); + }else if(arg.equals("shuffle")){ + shuffle = true; + }else if(arg.equals("list-tests")){ + listRunTests = true; + }else if(arg.equals("fail")){ + forceFail = true; + }else if(arg.equals("sqllog")){ + sqlLog = true; + }else if(arg.equals("configlog")){ + configLog = true; + }else if(arg.equals("naps")){ + takeNaps = true; + }else if(arg.equals("q") || arg.equals("quiet")){ + squelchTestOutput = true; + }else{ + throw new IllegalArgumentException("Unhandled flag:"+arg); + } + } + } + + if( sqlLog ){ + if( CApi.sqlite3_compileoption_used("ENABLE_SQLLOG") ){ + final ConfigSqllogCallback log = new ConfigSqllogCallback() { + @Override public void call(sqlite3 db, String msg, int op){ + switch(op){ + case 0: outln("Opening db: ",db); break; + case 1: outln("SQL ",db,": ",msg); break; + case 2: outln("Closing db: ",db); break; + } + } + }; + int rc = CApi.sqlite3_config( log ); + affirm( 0==rc ); + rc = CApi.sqlite3_config( (ConfigSqllogCallback)null ); + affirm( 0==rc ); + rc = CApi.sqlite3_config( log ); + affirm( 0==rc ); + }else{ + outln("WARNING: -sqllog is not active because library was built ", + "without SQLITE_ENABLE_SQLLOG."); + } + } + if( configLog ){ + final ConfigLogCallback log = new ConfigLogCallback() { + @Override public void call(int code, String msg){ + outln("ConfigLogCallback: ",ResultCode.getEntryForInt(code),": ", msg); + }; + }; + int rc = CApi.sqlite3_config( log ); + affirm( 0==rc ); + rc = CApi.sqlite3_config( (ConfigLogCallback)null ); + affirm( 0==rc ); + rc = CApi.sqlite3_config( log ); + affirm( 0==rc ); + } + + quietMode = squelchTestOutput; + outln("If you just saw warning messages regarding CallStaticObjectMethod, ", + "you are very likely seeing the side effects of a known openjdk8 ", + "bug. It is unsightly but does not affect the library."); + + { + // Build list of tests to run from the methods named test*(). + testMethods = new ArrayList<>(); + int nSkipped = 0; + for(final java.lang.reflect.Method m : Tester2.class.getDeclaredMethods()){ + final String name = m.getName(); + if( name.equals("testFail") ){ + if( forceFail ){ + testMethods.add(m); + } + }else if( !m.isAnnotationPresent( ManualTest.class ) ){ + if( nThread>1 && m.isAnnotationPresent( SingleThreadOnly.class ) ){ + if( 0==nSkipped++ ){ + out("Skipping tests in multi-thread mode:"); + } + out(" "+name+"()"); + }else if( name.startsWith("test") ){ + testMethods.add(m); + } + } + } + if( nSkipped>0 ) out("\n"); + } + + final long timeStart = System.currentTimeMillis(); + int nLoop = 0; + switch( CApi.sqlite3_threadsafe() ){ /* Sanity checking */ + case 0: + affirm( CApi.SQLITE_ERROR==CApi.sqlite3_config( CApi.SQLITE_CONFIG_SINGLETHREAD ), + "Could not switch to single-thread mode." ); + affirm( CApi.SQLITE_ERROR==CApi.sqlite3_config( CApi.SQLITE_CONFIG_MULTITHREAD ), + "Could switch to multithread mode." ); + affirm( CApi.SQLITE_ERROR==CApi.sqlite3_config( CApi.SQLITE_CONFIG_SERIALIZED ), + "Could not switch to serialized threading mode." ); + outln("This is a single-threaded build. Not using threads."); + nThread = 1; + break; + case 1: + case 2: + affirm( 0==CApi.sqlite3_config( CApi.SQLITE_CONFIG_SINGLETHREAD ), + "Could not switch to single-thread mode." ); + affirm( 0==CApi.sqlite3_config( CApi.SQLITE_CONFIG_MULTITHREAD ), + "Could not switch to multithread mode." ); + affirm( 0==CApi.sqlite3_config( CApi.SQLITE_CONFIG_SERIALIZED ), + "Could not switch to serialized threading mode." ); + break; + default: + affirm( false, "Unhandled SQLITE_THREADSAFE value." ); + } + outln("libversion_number: ", + CApi.sqlite3_libversion_number(),"\n", + CApi.sqlite3_libversion(),"\n",CApi.SQLITE_SOURCE_ID,"\n", + "SQLITE_THREADSAFE=",CApi.sqlite3_threadsafe()); + final boolean showLoopCount = (nRepeat>1 && nThread>1); + if( showLoopCount ){ + outln("Running ",nRepeat," loop(s) with ",nThread," thread(s) each."); + } + if( takeNaps ) outln("Napping between tests is enabled."); + for( int n = 0; n < nRepeat; ++n ){ + ++nLoop; + if( showLoopCount ) out((1==nLoop ? "" : " ")+nLoop); + if( nThread<=1 ){ + new Tester2(0).runTests(false); + continue; + } + Tester2.mtMode = true; + final ExecutorService ex = Executors.newFixedThreadPool( nThread ); + for( int i = 0; i < nThread; ++i ){ + ex.submit( new Tester2(i), i ); + } + ex.shutdown(); + try{ + ex.awaitTermination(nThread*200, java.util.concurrent.TimeUnit.MILLISECONDS); + ex.shutdownNow(); + }catch (InterruptedException ie){ + ex.shutdownNow(); + Thread.currentThread().interrupt(); + } + if( !listErrors.isEmpty() ){ + quietMode = false; + outln("TEST ERRORS:"); + Exception err = null; + for( Exception e : listErrors ){ + e.printStackTrace(); + if( null==err ) err = e; + } + if( null!=err ) throw err; + } + } + if( showLoopCount ) outln(); + quietMode = false; + + final long timeEnd = System.currentTimeMillis(); + outln("Tests done. Metrics across ",nTestRuns," total iteration(s):"); + outln("\tAssertions checked: ",affirmCount); + outln("\tDatabases opened: ",metrics.dbOpen); + if( doSomethingForDev ){ + CApi.sqlite3_jni_internal_details(); + } + affirm( 0==CApi.sqlite3_release_memory(1) ); + CApi.sqlite3_shutdown(); + int nMethods = 0; + int nNatives = 0; + int nCanonical = 0; + final java.lang.reflect.Method[] declaredMethods = + CApi.class.getDeclaredMethods(); + for(java.lang.reflect.Method m : declaredMethods){ + final int mod = m.getModifiers(); + if( 0!=(mod & java.lang.reflect.Modifier.STATIC) ){ + final String name = m.getName(); + if(name.startsWith("sqlite3_")){ + ++nMethods; + if( 0!=(mod & java.lang.reflect.Modifier.NATIVE) ){ + ++nNatives; + } + } + } + } + outln("\tCApi.sqlite3_*() methods: "+ + nMethods+" total, with "+ + nNatives+" native, "+ + (nMethods - nNatives)+" Java" + ); + outln("\tTotal test time = " + +(timeEnd - timeStart)+"ms"); + } +} diff --git a/ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java b/ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java new file mode 100644 index 0000000000..009936a43e --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java @@ -0,0 +1,25 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains a set of tests for the sqlite3 JNI bindings. +*/ +package org.sqlite.jni.wrapper1; + +/** + A helper class which simply holds a single value. Its primary use + is for communicating values out of anonymous classes, as doing so + requires a "final" reference. +*/ +public class ValueHolder { + public T value; + public ValueHolder(){} + public ValueHolder(T v){value = v;} +} diff --git a/ext/lsm1/lsm_vtab.c b/ext/lsm1/lsm_vtab.c index bb1460297d..8c21923e1a 100644 --- a/ext/lsm1/lsm_vtab.c +++ b/ext/lsm1/lsm_vtab.c @@ -1061,6 +1061,11 @@ static sqlite3_module lsm1Module = { lsm1Rollback, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; diff --git a/ext/misc/amatch.c b/ext/misc/amatch.c index bafa43283a..dd9bee53d7 100644 --- a/ext/misc/amatch.c +++ b/ext/misc/amatch.c @@ -1475,7 +1475,8 @@ static sqlite3_module amatchModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/btreeinfo.c b/ext/misc/btreeinfo.c index 22f8268139..02f8c0319c 100644 --- a/ext/misc/btreeinfo.c +++ b/ext/misc/btreeinfo.c @@ -411,7 +411,8 @@ int sqlite3BinfoRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "sqlite_btreeinfo", &binfo_module, 0); } diff --git a/ext/misc/carray.c b/ext/misc/carray.c index 709c894f27..b1caa98c3f 100644 --- a/ext/misc/carray.c +++ b/ext/misc/carray.c @@ -409,6 +409,11 @@ static sqlite3_module carrayModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadow */ + 0 /* xIntegrity */ }; /* diff --git a/ext/misc/closure.c b/ext/misc/closure.c index db9b2b7394..79a5a21d1e 100644 --- a/ext/misc/closure.c +++ b/ext/misc/closure.c @@ -939,7 +939,8 @@ static sqlite3_module closureModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/completion.c b/ext/misc/completion.c index d9e7b85972..987595a3d6 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -470,7 +470,8 @@ static sqlite3_module completionModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 870a0cf60e..b38500f4b9 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -897,6 +897,11 @@ static sqlite3_module CsvModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #ifdef SQLITE_TEST @@ -929,6 +934,11 @@ static sqlite3_module CsvModuleFauxWrite = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_TEST */ diff --git a/ext/misc/explain.c b/ext/misc/explain.c index 0095194570..726af76b96 100644 --- a/ext/misc/explain.c +++ b/ext/misc/explain.c @@ -293,6 +293,7 @@ static sqlite3_module explainModule = { 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/fileio.c b/ext/misc/fileio.c index 7cdbd5968f..70546adfca 100644 --- a/ext/misc/fileio.c +++ b/ext/misc/fileio.c @@ -983,6 +983,7 @@ static int fsdirRegister(sqlite3 *db){ 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0); diff --git a/ext/misc/fossildelta.c b/ext/misc/fossildelta.c index 6a597e0d7d..e638737d2b 100644 --- a/ext/misc/fossildelta.c +++ b/ext/misc/fossildelta.c @@ -1058,7 +1058,8 @@ static sqlite3_module deltaparsevtabModule = { /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; diff --git a/ext/misc/fuzzer.c b/ext/misc/fuzzer.c index 65d9d8df69..92b7c0dae0 100644 --- a/ext/misc/fuzzer.c +++ b/ext/misc/fuzzer.c @@ -1165,6 +1165,11 @@ static sqlite3_module fuzzerModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/memstat.c b/ext/misc/memstat.c index 800a86e7a4..c56af9f297 100644 --- a/ext/misc/memstat.c +++ b/ext/misc/memstat.c @@ -396,6 +396,7 @@ static sqlite3_module memstatModule = { 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/prefixes.c b/ext/misc/prefixes.c index 3f053b7f1c..e6517e7195 100644 --- a/ext/misc/prefixes.c +++ b/ext/misc/prefixes.c @@ -248,7 +248,8 @@ static sqlite3_module prefixesModule = { /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; /* diff --git a/ext/misc/qpvtab.c b/ext/misc/qpvtab.c index fb0c155a27..b7c2a05126 100644 --- a/ext/misc/qpvtab.c +++ b/ext/misc/qpvtab.c @@ -439,7 +439,8 @@ static sqlite3_module qpvtabModule = { /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/series.c b/ext/misc/series.c index 3bd567b2ef..abd6af7ad6 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -557,7 +557,8 @@ static sqlite3_module seriesModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index 3b78d9f07d..a0c5aafd10 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -3009,6 +3009,11 @@ static sqlite3_module spellfix1Module = { 0, /* xRollback */ 0, /* xFindMethod */ spellfix1Rename, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff --git a/ext/misc/stmt.c b/ext/misc/stmt.c index 4819cbe673..cc1aaa8493 100644 --- a/ext/misc/stmt.c +++ b/ext/misc/stmt.c @@ -314,6 +314,7 @@ static sqlite3_module stmtModule = { 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/templatevtab.c b/ext/misc/templatevtab.c index d7efa2b40e..5865f5214b 100644 --- a/ext/misc/templatevtab.c +++ b/ext/misc/templatevtab.c @@ -249,7 +249,8 @@ static sqlite3_module templatevtabModule = { /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; diff --git a/ext/misc/unionvtab.c b/ext/misc/unionvtab.c index 6ac7ca6e95..506ad5ddba 100644 --- a/ext/misc/unionvtab.c +++ b/ext/misc/unionvtab.c @@ -1351,7 +1351,8 @@ static int createUnionVtab(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; diff --git a/ext/misc/vfsstat.c b/ext/misc/vfsstat.c index 83a7a3df75..ba22115ab8 100644 --- a/ext/misc/vfsstat.c +++ b/ext/misc/vfsstat.c @@ -775,6 +775,11 @@ static sqlite3_module VfsStatModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff --git a/ext/misc/vtablog.c b/ext/misc/vtablog.c index 424b3457ff..e414e7afa7 100644 --- a/ext/misc/vtablog.c +++ b/ext/misc/vtablog.c @@ -493,6 +493,7 @@ static sqlite3_module vtablogModule = { 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; #ifdef _WIN32 diff --git a/ext/misc/wholenumber.c b/ext/misc/wholenumber.c index 03d6e6902e..4c955925da 100644 --- a/ext/misc/wholenumber.c +++ b/ext/misc/wholenumber.c @@ -254,6 +254,11 @@ static sqlite3_module wholenumberModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index 4dbf80b197..416a49443b 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -2200,7 +2200,8 @@ static int zipfileRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollback */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0); diff --git a/ext/recover/dbdata.c b/ext/recover/dbdata.c index e3bec33d8d..25a6e9fd6a 100644 --- a/ext/recover/dbdata.c +++ b/ext/recover/dbdata.c @@ -933,7 +933,8 @@ static int sqlite3DbdataRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0); diff --git a/ext/repair/checkindex.c b/ext/repair/checkindex.c index 080a51530d..5f6e646e44 100644 --- a/ext/repair/checkindex.c +++ b/ext/repair/checkindex.c @@ -907,6 +907,8 @@ static int ciInit(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "incremental_index_check", &cidx_module, 0); } diff --git a/ext/rtree/geopoly.c b/ext/rtree/geopoly.c index a0194680c3..3e9c2a2713 100644 --- a/ext/rtree/geopoly.c +++ b/ext/rtree/geopoly.c @@ -1252,6 +1252,7 @@ static int geopolyInit( (void)pAux; sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); /* Allocate the sqlite3_vtab structure */ nDb = strlen(argv[1]); @@ -1782,7 +1783,8 @@ static sqlite3_module geopolyModule = { rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - rtreeShadowName /* xShadowName */ + rtreeShadowName, /* xShadowName */ + rtreeIntegrity /* xIntegrity */ }; static int sqlite3_geopoly_init(sqlite3 *db){ diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 8f01be37f6..682c052c56 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3615,6 +3615,8 @@ static int rtreeInit( } sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + /* Allocate the sqlite3_vtab structure */ nDb = (int)strlen(argv[1]); @@ -4130,7 +4132,6 @@ static int rtreeCheckTable( ){ RtreeCheck check; /* Common context for various routines */ sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ - int bEnd = 0; /* True if transaction should be closed */ int nAux = 0; /* Number of extra columns. */ /* Initialize the context object */ @@ -4139,14 +4140,6 @@ static int rtreeCheckTable( check.zDb = zDb; check.zTab = zTab; - /* If there is not already an open transaction, open one now. This is - ** to ensure that the queries run as part of this integrity-check operate - ** on a consistent snapshot. */ - if( sqlite3_get_autocommit(db) ){ - check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); - bEnd = 1; - } - /* Find the number of auxiliary columns */ if( check.rc==SQLITE_OK ){ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); @@ -4187,11 +4180,6 @@ static int rtreeCheckTable( sqlite3_finalize(check.aCheckMapping[0]); sqlite3_finalize(check.aCheckMapping[1]); - /* If one was opened, close the transaction */ - if( bEnd ){ - int rc = sqlite3_exec(db, "END", 0, 0, 0); - if( check.rc==SQLITE_OK ) check.rc = rc; - } *pzReport = check.zReport; return check.rc; } diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index 633d0a5d5f..2d8458a538 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -784,4 +784,15 @@ do_execsql_test 22.1 { SELECT id, x0 > 9223372036854775807 AS 'a0' FROM t1; } {123 1} +# 2023-10-14 dbsqlfuzz --sql-fuzz find. rtreecheck() should not call +# BEGIN/COMMIT because that causes problems with statement transactions, +# and it is unnecessary. +# +reset_db +do_test 23.0 { + db eval {CREATE TABLE t1(a,b,c);} + catch {db eval {CREATE TABLE t2 AS SELECT rtreecheck('t1') AS y;}} + db eval {PRAGMA integrity_check;} +} {ok} + finish_test diff --git a/ext/session/session3.test b/ext/session/session3.test index ba316348ef..ee955f1376 100644 --- a/ext/session/session3.test +++ b/ext/session/session3.test @@ -135,8 +135,8 @@ do_test 2.2.2 { DROP TABLE t2; CREATE TABLE t2(a, b PRIMARY KEY, c, d); } - list [catch { S changeset } msg] $msg -} {1 SQLITE_SCHEMA} + catch { S changeset } +} {0} do_test 2.2.3 { S delete sqlite3session S db main @@ -167,8 +167,8 @@ do_test 2.2.4 { CREATE TABLE t2(a, b PRIMARY KEY, c, d); INSERT INTO t2 VALUES(4, 5, 6, 7); } - list [catch { S changeset } msg] $msg -} {1 SQLITE_SCHEMA} + catch { S changeset } +} {0} do_test 2.3 { S delete diff --git a/ext/session/sessionalter.test b/ext/session/sessionalter.test new file mode 100644 index 0000000000..96a810d8c7 --- /dev/null +++ b/ext/session/sessionalter.test @@ -0,0 +1,237 @@ +# 2023 October 02 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements that the sessions module interacts well with +# the ALTER TABLE ADD COLUMN command. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl + +ifcapable !session {finish_test; return} +set testprefix sessionalter + + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); +} + +do_execsql_test -db db2 1.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c DEFAULT 1234); +} + +do_then_apply_sql { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); +} + +do_execsql_test -db db2 1.2 { + SELECT * FROM t1 +} { + 1 one 1234 + 2 two 1234 +} + +do_then_apply_sql { + UPDATE t1 SET b='four' WHERE a=2; +} + +do_execsql_test -db db2 1.3 { + SELECT * FROM t1 +} { + 1 one 1234 + 2 four 1234 +} + +do_then_apply_sql { + DELETE FROM t1 WHERE a=1; +} + +do_execsql_test -db db2 1.4 { + SELECT * FROM t1 +} { + 2 four 1234 +} + + +#-------------------------------------------------------------------------- +reset_db + +do_execsql_test 2.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); +} + +do_test 2.1 { + sqlite3session S db main + S attach t1 + set {} {} +} {} +do_execsql_test 2.2 { + INSERT INTO t1 VALUES(1, 2); + ALTER TABLE t1 ADD COLUMN c DEFAULT 'abcd'; + INSERT INTO t1 VALUES(2, 3, 4); +} +do_changeset_test 2.3 S { + {INSERT t1 0 X.. {} {i 1 i 2 t abcd}} + {INSERT t1 0 X.. {} {i 2 i 3 i 4}} +} + +do_iterator_test 2.4 {} { + DELETE FROM t1 WHERE a=2; + ALTER TABLE t1 ADD COLUMN d DEFAULT 'abcd'; + ALTER TABLE t1 ADD COLUMN e DEFAULT 5; + ALTER TABLE t1 ADD COLUMN f DEFAULT 7.2; + -- INSERT INTO t1 VALUES(9, 9, 9, 9); +} { + {DELETE t1 0 X..... {i 2 i 3 i 4 t abcd i 5 f 7.2} {}} +} + +#------------------------------------------------------------------------- +# Tests of the sqlite3changegroup_xxx() APIs. +# +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + CREATE TABLE t2(x PRIMARY KEY, y); + CREATE TABLE t3(x, y); + CREATE TABLE t4(y PRIMARY KEY, x) WITHOUT ROWID; + + INSERT INTO t1 VALUES(1, 2), (3, 4), (5, 6); + INSERT INTO t2 VALUES('one', 'two'), ('three', 'four'), ('five', 'six'); + INSERT INTO t3 VALUES(1, 2), (3, 4), (5, 6); + + INSERT INTO t4(x, y) VALUES(1, 2), (3, 4), (5, 6); +} + +db_save_and_close +foreach {tn sql1 at sql2} { + 1 { + INSERT INTO t1(x, y) VALUES(7, 8); + } { + ALTER TABLE t1 ADD COLUMN z DEFAULT 10; + } { + UPDATE t1 SET y=11 WHERE x=7; + } + + 2 { + UPDATE t2 SET y='two.two' WHERE x='one'; + DELETE FROM t2 WHERE x='five'; + INSERT INTO t2(x, y) VALUES('seven', 'eight'); + } { + ALTER TABLE t2 ADD COLUMN z; + ALTER TABLE t2 ADD COLUMN zz; + } { + } + + 3 { + DELETE FROM t2 WHERE x='five'; + } { + ALTER TABLE t2 ADD COLUMN z DEFAULT 'xyz'; + } { + } + + 4 { + UPDATE t2 SET y='two.two' WHERE x='three'; + } { + ALTER TABLE t2 ADD COLUMN z; + } { + UPDATE t2 SET z='abc' WHERE x='one'; + } + + 5* { + UPDATE t2 SET y='two.two' WHERE x='three'; + } { + ALTER TABLE t2 ADD COLUMN z DEFAULT 'defu1'; + } { + } + + 6* { + INSERT INTO t2(x, y) VALUES('nine', 'ten'); + } { + ALTER TABLE t2 ADD COLUMN z; + ALTER TABLE t2 ADD COLUMN a DEFAULT 'eelve'; + ALTER TABLE t2 ADD COLUMN b DEFAULT x'1234abcd'; + ALTER TABLE t2 ADD COLUMN c DEFAULT 4.2; + ALTER TABLE t2 ADD COLUMN d DEFAULT NULL; + } { + } + + 7 { + INSERT INTO t3(x, y) VALUES(7, 8); + UPDATE t3 SET y='fourteen' WHERE x=1; + DELETE FROM t3 WHERE x=3; + } { + ALTER TABLE t3 ADD COLUMN c; + } { + INSERT INTO t3(x, y, c) VALUES(9, 10, 11); + } + + 8 { + INSERT INTO t4(x, y) VALUES(7, 8); + UPDATE t4 SET y='fourteen' WHERE x=1; + DELETE FROM t4 WHERE x=3; + } { + ALTER TABLE t4 ADD COLUMN c; + } { + INSERT INTO t4(x, y, c) VALUES(9, 10, 11); + } +} { + foreach {tn2 cmd} { + 1 changeset_from_sql + 2 patchset_from_sql + } { + db_restore_and_reopen + + set C1 [$cmd $sql1] + execsql $at + set C2 [$cmd $sql2] + + sqlite3changegroup grp + grp schema db main + grp add $C1 + grp add $C2 + set T1 [grp output] + grp delete + + db_restore_and_reopen + execsql $at + set T2 [$cmd "$sql1 ; $sql2"] + + if {[string range $tn end end]!="*"} { + do_test 3.1.$tn.$tn2.1 { changeset_to_list $T1 } [changeset_to_list $T2] + set testname "$tn.$tn2" + } else { + set testname "[string range $tn 0 end-1].$tn2" + } + + db_restore_and_reopen + proc xConflict {args} { return "REPLACE" } + sqlite3changeset_apply_v2 db $T1 xConflict + set S1 [scksum db main] + + db_restore_and_reopen + sqlite3changeset_apply_v2 db $T2 xConflict + set S2 [scksum db main] + + # if { $tn==7 } { puts [changeset_to_list $T1] } + + do_test 3.1.$tn.2 { set S1 } $S2 + } +} + + +finish_test + diff --git a/ext/session/sessionfault3.test b/ext/session/sessionfault3.test new file mode 100644 index 0000000000..af5a4cdb43 --- /dev/null +++ b/ext/session/sessionfault3.test @@ -0,0 +1,59 @@ +# 2016 October 6 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The focus of this file is testing the session module. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} +set testprefix sessionfault3 + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, PRIMARY KEY(a)); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES('five', 'six'); +} + +set C1 [changeset_from_sql { + INSERT INTO t1 VALUES('seven', 'eight'); + UPDATE t1 SET b=6 WHERE a='five'; + DELETE FROM t1 WHERE a=1; +}] + +do_execsql_test 1.1 { + ALTER TABLE t1 ADD COLUMN d DEFAULT 123; + ALTER TABLE t1 ADD COLUMN e DEFAULT 'string'; +} + +set C2 [changeset_from_sql { + UPDATE t1 SET e='new value' WHERE a='seven'; + INSERT INTO t1 VALUES(0, 0, 0, 0); +}] + +do_faultsim_test 1 -faults oom* -prep { + sqlite3changegroup G +} -body { + G schema db main + G add $::C1 + G add $::C2 + G output + set {} {} +} -test { + catch { G delete } + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} +} + +finish_test diff --git a/ext/session/sessionnoact.test b/ext/session/sessionnoact.test new file mode 100644 index 0000000000..1274ecb146 --- /dev/null +++ b/ext/session/sessionnoact.test @@ -0,0 +1,110 @@ +# 2023 October 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionnoact + +do_execsql_test 1.0 { + CREATE TABLE p1(a INTEGER PRIMARY KEY, b, c UNIQUE); + INSERT INTO p1 VALUES(1, 1, 'one'); + INSERT INTO p1 VALUES(2, 2, 'two'); + INSERT INTO p1 VALUES(3, 3, 'three'); + INSERT INTO p1 VALUES(4, 4, 'four'); +} + +db_save + +set C [changeset_from_sql { + DELETE FROM p1 WHERE a=2; + UPDATE p1 SET c='six' WHERE a=3; + INSERT INTO p1 VALUES(5, 5, 'two'); + INSERT INTO p1 VALUES(6, 6, 'three'); +}] + +db_restore_and_reopen + +do_execsql_test 1.1 { + CREATE TABLE c1(x INTEGER PRIMARY KEY, y, + FOREIGN KEY(y) REFERENCES p1(c) ON DELETE CASCADE ON UPDATE SET NULL + ); + + INSERT INTO c1 VALUES(10, 'one'); + INSERT INTO c1 VALUES(20, 'two'); + INSERT INTO c1 VALUES(30, 'three'); + INSERT INTO c1 VALUES(40, 'four'); +} + +db_save + +do_execsql_test 1.2 { + PRAGMA foreign_keys = 1; +} + +set ::nConflict 0 +proc conflict {args} { + incr ::nConflict + return "OMIT" +} + +sqlite3changeset_apply_v2 db $C conflict + +do_execsql_test 1.3 { + SELECT * FROM c1 +} { + 10 one + 30 {} + 40 four +} + +db_restore_and_reopen + +do_execsql_test 1.4 { + PRAGMA foreign_keys = 1; +} + +do_execsql_test 1.5 { + UPDATE p1 SET c=12345 WHERE a = 45; +} + +sqlite3changeset_apply_v2 -noaction db $C conflict +do_execsql_test 1.6 { + SELECT * FROM c1 +} { + 10 one + 20 two + 30 three + 40 four +} + +do_execsql_test 1.7 { + PRAGMA foreign_keys = 1; + UPDATE p1 SET c = 'ten' WHERE c='two'; + SELECT * FROM c1; +} { + 10 one + 20 {} + 30 three + 40 four +} + +do_execsql_test 1.8 { + PRAGMA foreign_key_check +} + +finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 0491549231..e7459b1af9 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -119,6 +119,18 @@ struct sqlite3_changeset_iter { ** The data associated with each hash-table entry is a structure containing ** a subset of the initial values that the modified row contained at the ** start of the session. Or no initial values if the row was inserted. +** +** pDfltStmt: +** This is only used by the sqlite3changegroup_xxx() APIs, not by +** regular sqlite3_session objects. It is a SELECT statement that +** selects the default value for each table column. For example, +** if the table is +** +** CREATE TABLE xx(a DEFAULT 1, b, c DEFAULT 'abc') +** +** then this variable is the compiled version of: +** +** SELECT 1, NULL, 'abc' */ struct SessionTable { SessionTable *pNext; @@ -127,10 +139,12 @@ struct SessionTable { int bStat1; /* True if this is sqlite_stat1 */ int bRowid; /* True if this table uses rowid for PK */ const char **azCol; /* Column names */ + const char **azDflt; /* Default value expressions */ u8 *abPK; /* Array of primary key flags */ int nEntry; /* Total number of entries in hash table */ int nChange; /* Size of apChange[] array */ SessionChange **apChange; /* Hash table buckets */ + sqlite3_stmt *pDfltStmt; }; /* @@ -299,6 +313,7 @@ struct SessionTable { struct SessionChange { u8 op; /* One of UPDATE, DELETE, INSERT */ u8 bIndirect; /* True if this change is "indirect" */ + u16 nRecordField; /* Number of fields in aRecord[] */ int nMaxSize; /* Max size of eventual changeset record */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ @@ -324,7 +339,7 @@ static int sessionVarintLen(int iVal){ ** Read a varint value from aBuf[] into *piVal. Return the number of ** bytes read. */ -static int sessionVarintGet(u8 *aBuf, int *piVal){ +static int sessionVarintGet(const u8 *aBuf, int *piVal){ return getVarint32(aBuf, *piVal); } @@ -587,7 +602,7 @@ static int sessionPreupdateHash( ** Return the number of bytes of space occupied by the value (including ** the type byte). */ -static int sessionSerialLen(u8 *a){ +static int sessionSerialLen(const u8 *a){ int e = *a; int n; if( e==0 || e==0xFF ) return 1; @@ -994,13 +1009,14 @@ static int sessionGrowHash( ** ** For example, if the table is declared as: ** -** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z)); +** CREATE TABLE tbl1(w, x DEFAULT 'abc', y, z, PRIMARY KEY(w, z)); ** -** Then the four output variables are populated as follows: +** Then the five output variables are populated as follows: ** ** *pnCol = 4 ** *pzTab = "tbl1" ** *pazCol = {"w", "x", "y", "z"} +** *pazDflt = {NULL, 'abc', NULL, NULL} ** *pabPK = {1, 0, 0, 1} ** ** All returned buffers are part of the same single allocation, which must @@ -1014,6 +1030,7 @@ static int sessionTableInfo( int *pnCol, /* OUT: number of columns */ const char **pzTab, /* OUT: Copy of zThis */ const char ***pazCol, /* OUT: Array of column names for table */ + const char ***pazDflt, /* OUT: Array of default value expressions */ u8 **pabPK, /* OUT: Array of booleans - true for PK col */ int *pbRowid /* OUT: True if only PK is a rowid */ ){ @@ -1026,11 +1043,18 @@ static int sessionTableInfo( int i; u8 *pAlloc = 0; char **azCol = 0; + char **azDflt = 0; u8 *abPK = 0; int bRowid = 0; /* Set to true to use rowid as PK */ assert( pazCol && pabPK ); + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; + if( pazDflt ) *pazDflt = 0; + nThis = sqlite3Strlen30(zThis); if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){ rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0); @@ -1044,39 +1068,28 @@ static int sessionTableInfo( }else if( rc==SQLITE_ERROR ){ zPragma = sqlite3_mprintf(""); }else{ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return rc; } }else{ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); } if( !zPragma ){ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return SQLITE_NOMEM; } rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); sqlite3_free(zPragma); if( rc!=SQLITE_OK ){ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return rc; } nByte = nThis + 1; bRowid = (pbRowid!=0); while( SQLITE_ROW==sqlite3_step(pStmt) ){ - nByte += sqlite3_column_bytes(pStmt, 1); + nByte += sqlite3_column_bytes(pStmt, 1); /* name */ + nByte += sqlite3_column_bytes(pStmt, 4); /* dflt_value */ nDbCol++; - if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; + if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; /* pk */ } if( nDbCol==0 ) bRowid = 0; nDbCol += bRowid; @@ -1084,15 +1097,18 @@ static int sessionTableInfo( rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ){ - nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); + nByte += nDbCol * (sizeof(const char *)*2 + sizeof(u8) + 1 + 1); pAlloc = sessionMalloc64(pSession, nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; + }else{ + memset(pAlloc, 0, nByte); } } if( rc==SQLITE_OK ){ azCol = (char **)pAlloc; - pAlloc = (u8 *)&azCol[nDbCol]; + azDflt = (char**)&azCol[nDbCol]; + pAlloc = (u8 *)&azDflt[nDbCol]; abPK = (u8 *)pAlloc; pAlloc = &abPK[nDbCol]; if( pzTab ){ @@ -1112,11 +1128,21 @@ static int sessionTableInfo( } while( SQLITE_ROW==sqlite3_step(pStmt) ){ int nName = sqlite3_column_bytes(pStmt, 1); + int nDflt = sqlite3_column_bytes(pStmt, 4); const unsigned char *zName = sqlite3_column_text(pStmt, 1); + const unsigned char *zDflt = sqlite3_column_text(pStmt, 4); + if( zName==0 ) break; memcpy(pAlloc, zName, nName+1); azCol[i] = (char *)pAlloc; pAlloc += nName+1; + if( zDflt ){ + memcpy(pAlloc, zDflt, nDflt+1); + azDflt[i] = (char *)pAlloc; + pAlloc += nDflt+1; + }else{ + azDflt[i] = 0; + } abPK[i] = sqlite3_column_int(pStmt, 5); i++; } @@ -1127,14 +1153,11 @@ static int sessionTableInfo( ** free any allocation made. An error code will be returned in this case. */ if( rc==SQLITE_OK ){ - *pazCol = (const char **)azCol; + *pazCol = (const char**)azCol; + if( pazDflt ) *pazDflt = (const char**)azDflt; *pabPK = abPK; *pnCol = nDbCol; }else{ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; sessionFree(pSession, azCol); } if( pbRowid ) *pbRowid = bRowid; @@ -1143,10 +1166,9 @@ static int sessionTableInfo( } /* -** This function is only called from within a pre-update handler for a -** write to table pTab, part of session pSession. If this is the first -** write to this table, initalize the SessionTable.nCol, azCol[] and -** abPK[] arrays accordingly. +** This function is called to initialize the SessionTable.nCol, azCol[] +** abPK[] and azDflt[] members of SessionTable object pTab. If these +** fields are already initilialized, this function is a no-op. ** ** If an error occurs, an error code is stored in sqlite3_session.rc and ** non-zero returned. Or, if no error occurs but the table has no primary @@ -1154,15 +1176,22 @@ static int sessionTableInfo( ** indicate that updates on this table should be ignored. SessionTable.abPK ** is set to NULL in this case. */ -static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ +static int sessionInitTable( + sqlite3_session *pSession, /* Optional session handle */ + SessionTable *pTab, /* Table object to initialize */ + sqlite3 *db, /* Database handle to read schema from */ + const char *zDb /* Name of db - "main", "temp" etc. */ +){ + int rc = SQLITE_OK; + if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); - pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, - pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK, - (pSession->bImplicitPK ? &pTab->bRowid : 0) + rc = sessionTableInfo(pSession, db, zDb, + pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->azDflt, &abPK, + ((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0) ); - if( pSession->rc==SQLITE_OK ){ + if( rc==SQLITE_OK ){ int i; for(i=0; inCol; i++){ if( abPK[i] ){ @@ -1174,14 +1203,321 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ pTab->bStat1 = 1; } - if( pSession->bEnableSize ){ + if( pSession && pSession->bEnableSize ){ pSession->nMaxChangesetSize += ( 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1 ); } } } - return (pSession->rc || pTab->abPK==0); + + if( pSession ){ + pSession->rc = rc; + return (rc || pTab->abPK==0); + } + return rc; +} + +/* +** Re-initialize table object pTab. +*/ +static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){ + int nCol = 0; + const char **azCol = 0; + const char **azDflt = 0; + u8 *abPK = 0; + int bRowid = 0; + + assert( pSession->rc==SQLITE_OK ); + + pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, + pTab->zName, &nCol, 0, &azCol, &azDflt, &abPK, + (pSession->bImplicitPK ? &bRowid : 0) + ); + if( pSession->rc==SQLITE_OK ){ + if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){ + pSession->rc = SQLITE_SCHEMA; + }else{ + int ii; + int nOldCol = pTab->nCol; + for(ii=0; iinCol ){ + if( pTab->abPK[ii]!=abPK[ii] ){ + pSession->rc = SQLITE_SCHEMA; + } + }else if( abPK[ii] ){ + pSession->rc = SQLITE_SCHEMA; + } + } + + if( pSession->rc==SQLITE_OK ){ + const char **a = pTab->azCol; + pTab->azCol = azCol; + pTab->nCol = nCol; + pTab->azDflt = azDflt; + pTab->abPK = abPK; + azCol = a; + } + if( pSession->bEnableSize ){ + pSession->nMaxChangesetSize += (nCol - nOldCol); + pSession->nMaxChangesetSize += sessionVarintLen(nCol); + pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol); + } + } + } + + sqlite3_free(azCol); + return pSession->rc; +} + +/* +** Session-change object (*pp) contains an old.* record with fewer than +** nCol fields. This function updates it with the default values for +** the missing fields. +*/ +static void sessionUpdateOneChange( + sqlite3_session *pSession, /* For memory accounting */ + int *pRc, /* IN/OUT: Error code */ + SessionChange **pp, /* IN/OUT: Change object to update */ + int nCol, /* Number of columns now in table */ + sqlite3_stmt *pDflt /* SELECT */ +){ + SessionChange *pOld = *pp; + + while( pOld->nRecordFieldnRecordField; + int eType = sqlite3_column_type(pDflt, iField); + switch( eType ){ + case SQLITE_NULL: + nIncr = 1; + break; + case SQLITE_INTEGER: + case SQLITE_FLOAT: + nIncr = 9; + break; + default: { + int n = sqlite3_column_bytes(pDflt, iField); + nIncr = 1 + sessionVarintLen(n) + n; + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + break; + } + } + + nByte = nIncr + (sizeof(SessionChange) + pOld->nRecord); + pNew = sessionMalloc64(pSession, nByte); + if( pNew==0 ){ + *pRc = SQLITE_NOMEM; + return; + }else{ + memcpy(pNew, pOld, sizeof(SessionChange)); + pNew->aRecord = (u8*)&pNew[1]; + memcpy(pNew->aRecord, pOld->aRecord, pOld->nRecord); + pNew->aRecord[pNew->nRecord++] = (u8)eType; + switch( eType ){ + case SQLITE_INTEGER: { + i64 iVal = sqlite3_column_int64(pDflt, iField); + sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); + pNew->nRecord += 8; + break; + } + + case SQLITE_FLOAT: { + double rVal = sqlite3_column_double(pDflt, iField); + i64 iVal = 0; + memcpy(&iVal, &rVal, sizeof(rVal)); + sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); + pNew->nRecord += 8; + break; + } + + case SQLITE_TEXT: { + int n = sqlite3_column_bytes(pDflt, iField); + const char *z = (const char*)sqlite3_column_text(pDflt, iField); + pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n); + memcpy(&pNew->aRecord[pNew->nRecord], z, n); + pNew->nRecord += n; + break; + } + + case SQLITE_BLOB: { + int n = sqlite3_column_bytes(pDflt, iField); + const u8 *z = (const u8*)sqlite3_column_blob(pDflt, iField); + pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n); + memcpy(&pNew->aRecord[pNew->nRecord], z, n); + pNew->nRecord += n; + break; + } + + default: + assert( eType==SQLITE_NULL ); + break; + } + + sessionFree(pSession, pOld); + *pp = pOld = pNew; + pNew->nRecordField++; + pNew->nMaxSize += nIncr; + if( pSession ){ + pSession->nMaxChangesetSize += nIncr; + } + } + } +} + +/* +** Ensure that there is room in the buffer to append nByte bytes of data. +** If not, use sqlite3_realloc() to grow the buffer so that there is. +** +** If successful, return zero. Otherwise, if an OOM condition is encountered, +** set *pRc to SQLITE_NOMEM and return non-zero. +*/ +static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ +#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) + i64 nReq = p->nBuf + nByte; + if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ + u8 *aNew; + i64 nNew = p->nAlloc ? p->nAlloc : 128; + + do { + nNew = nNew*2; + }while( nNewSESSION_MAX_BUFFER_SZ ){ + nNew = SESSION_MAX_BUFFER_SZ; + if( nNewaBuf, nNew); + if( 0==aNew ){ + *pRc = SQLITE_NOMEM; + }else{ + p->aBuf = aNew; + p->nAlloc = nNew; + } + } + return (*pRc!=SQLITE_OK); +} + + +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append a string to the buffer. All bytes in the string +** up to (but not including) the nul-terminator are written to the buffer. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ +static void sessionAppendStr( + SessionBuffer *p, + const char *zStr, + int *pRc +){ + int nStr = sqlite3Strlen30(zStr); + if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ + memcpy(&p->aBuf[p->nBuf], zStr, nStr); + p->nBuf += nStr; + p->aBuf[p->nBuf] = 0x00; + } +} + +/* +** Format a string using printf() style formatting and then append it to the +** buffer using sessionAppendString(). +*/ +static void sessionAppendPrintf( + SessionBuffer *p, /* Buffer to append to */ + int *pRc, + const char *zFmt, + ... +){ + if( *pRc==SQLITE_OK ){ + char *zApp = 0; + va_list ap; + va_start(ap, zFmt); + zApp = sqlite3_vmprintf(zFmt, ap); + if( zApp==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + sessionAppendStr(p, zApp, pRc); + } + va_end(ap); + sqlite3_free(zApp); + } +} + +/* +** Prepare a statement against database handle db that SELECTs a single +** row containing the default values for each column in table pTab. For +** example, if pTab is declared as: +** +** CREATE TABLE pTab(a PRIMARY KEY, b DEFAULT 123, c DEFAULT 'abcd'); +** +** Then this function prepares and returns the SQL statement: +** +** SELECT NULL, 123, 'abcd'; +*/ +static int sessionPrepareDfltStmt( + sqlite3 *db, /* Database handle */ + SessionTable *pTab, /* Table to prepare statement for */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + SessionBuffer sql = {0,0,0}; + int rc = SQLITE_OK; + const char *zSep = " "; + int ii = 0; + + *ppStmt = 0; + sessionAppendPrintf(&sql, &rc, "SELECT"); + for(ii=0; iinCol; ii++){ + const char *zDflt = pTab->azDflt[ii] ? pTab->azDflt[ii] : "NULL"; + sessionAppendPrintf(&sql, &rc, "%s%s", zSep, zDflt); + zSep = ", "; + } + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, (const char*)sql.aBuf, -1, ppStmt, 0); + } + sqlite3_free(sql.aBuf); + + return rc; +} + +/* +** Table pTab has one or more existing change-records with old.* records +** with fewer than pTab->nCol columns. This function updates all such +** change-records with the default values for the missing columns. +*/ +static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){ + sqlite3_stmt *pStmt = 0; + int rc = pSession->rc; + + rc = sessionPrepareDfltStmt(pSession->db, pTab, &pStmt); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + int ii = 0; + SessionChange **pp = 0; + for(ii=0; iinChange; ii++){ + for(pp=&pTab->apChange[ii]; *pp; pp=&((*pp)->pNext)){ + if( (*pp)->nRecordField!=pTab->nCol ){ + sessionUpdateOneChange(pSession, &rc, pp, pTab->nCol, pStmt); + } + } + } + } + + pSession->rc = rc; + rc = sqlite3_finalize(pStmt); + if( pSession->rc==SQLITE_OK ) pSession->rc = rc; + return pSession->rc; } /* @@ -1344,16 +1680,22 @@ static void sessionPreupdateOneChange( int iHash; int bNull = 0; int rc = SQLITE_OK; + int nExpect = 0; SessionStat1Ctx stat1 = {{0,0,0,0,0},0}; if( pSession->rc ) return; /* Load table details if required */ - if( sessionInitTable(pSession, pTab) ) return; + if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return; /* Check the number of columns in this xPreUpdate call matches the ** number of columns in the table. */ - if( (pTab->nCol-pTab->bRowid)!=pSession->hook.xCount(pSession->hook.pCtx) ){ + nExpect = pSession->hook.xCount(pSession->hook.pCtx); + if( (pTab->nCol-pTab->bRowid)nCol-pTab->bRowid)!=nExpect ){ pSession->rc = SQLITE_SCHEMA; return; } @@ -1430,7 +1772,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pC = (SessionChange *)sessionMalloc64(pSession, nByte); + pC = (SessionChange*)sessionMalloc64(pSession, nByte); if( !pC ){ rc = SQLITE_NOMEM; goto error_out; @@ -1463,6 +1805,7 @@ static void sessionPreupdateOneChange( if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){ pC->bIndirect = 1; } + pC->nRecordField = pTab->nCol; pC->nRecord = nByte; pC->op = op; pC->pNext = pTab->apChange[iHash]; @@ -1842,7 +2185,7 @@ int sqlite3session_diff( /* Locate and if necessary initialize the target table object */ rc = sessionFindTable(pSession, zTbl, &pTo); if( pTo==0 ) goto diff_out; - if( sessionInitTable(pSession, pTo) ){ + if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){ rc = pSession->rc; goto diff_out; } @@ -1855,7 +2198,7 @@ int sqlite3session_diff( int bRowid = 0; u8 *abPK; const char **azCol = 0; - rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK, + rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, 0, &abPK, pSession->bImplicitPK ? &bRowid : 0 ); if( rc==SQLITE_OK ){ @@ -1970,6 +2313,7 @@ static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){ sessionFree(pSession, p); } } + sqlite3_finalize(pTab->pDfltStmt); sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */ sessionFree(pSession, pTab->apChange); sessionFree(pSession, pTab); @@ -2004,7 +2348,7 @@ void sqlite3session_delete(sqlite3_session *pSession){ /* Assert that all allocations have been freed and then free the ** session object itself. */ - assert( pSession->nMalloc==0 ); + // assert( pSession->nMalloc==0 ); sqlite3_free(pSession); } @@ -2075,48 +2419,6 @@ int sqlite3session_attach( return rc; } -/* -** Ensure that there is room in the buffer to append nByte bytes of data. -** If not, use sqlite3_realloc() to grow the buffer so that there is. -** -** If successful, return zero. Otherwise, if an OOM condition is encountered, -** set *pRc to SQLITE_NOMEM and return non-zero. -*/ -static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ -#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) - i64 nReq = p->nBuf + nByte; - if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ - u8 *aNew; - i64 nNew = p->nAlloc ? p->nAlloc : 128; - - do { - nNew = nNew*2; - }while( nNewSESSION_MAX_BUFFER_SZ ){ - nNew = SESSION_MAX_BUFFER_SZ; - if( nNewaBuf, nNew); - if( 0==aNew ){ - *pRc = SQLITE_NOMEM; - }else{ - p->aBuf = aNew; - p->nAlloc = nNew; - } - } - return (*pRc!=SQLITE_OK); -} - /* ** Append the value passed as the second argument to the buffer passed ** as the first. @@ -2185,27 +2487,6 @@ static void sessionAppendBlob( } } -/* -** This function is a no-op if *pRc is other than SQLITE_OK when it is -** called. Otherwise, append a string to the buffer. All bytes in the string -** up to (but not including) the nul-terminator are written to the buffer. -** -** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before -** returning. -*/ -static void sessionAppendStr( - SessionBuffer *p, - const char *zStr, - int *pRc -){ - int nStr = sqlite3Strlen30(zStr); - if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ - memcpy(&p->aBuf[p->nBuf], zStr, nStr); - p->nBuf += nStr; - p->aBuf[p->nBuf] = 0x00; - } -} - /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string representation of integer iVal @@ -2224,27 +2505,6 @@ static void sessionAppendInteger( sessionAppendStr(p, aBuf, pRc); } -static void sessionAppendPrintf( - SessionBuffer *p, /* Buffer to append to */ - int *pRc, - const char *zFmt, - ... -){ - if( *pRc==SQLITE_OK ){ - char *zApp = 0; - va_list ap; - va_start(ap, zFmt); - zApp = sqlite3_vmprintf(zFmt, ap); - if( zApp==0 ){ - *pRc = SQLITE_NOMEM; - }else{ - sessionAppendStr(p, zApp, pRc); - } - va_end(ap); - sqlite3_free(zApp); - } -} - /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string zStr enclosed in quotes (") and @@ -2735,26 +2995,16 @@ static int sessionGenerateChangeset( for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ const char *zName = pTab->zName; - int nCol = 0; /* Number of columns in table */ - u8 *abPK = 0; /* Primary key array */ - const char **azCol = 0; /* Table columns */ int i; /* Used to iterate through hash buckets */ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ int nRewind = buf.nBuf; /* Initial size of write buffer */ int nNoop; /* Size of buffer after writing tbl header */ - int bRowid = 0; + int nOldCol = pTab->nCol; /* Check the table schema is still Ok. */ - rc = sessionTableInfo( - 0, db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK, - (pSession->bImplicitPK ? &bRowid : 0) - ); - if( rc==SQLITE_OK && ( - pTab->nCol!=nCol - || pTab->bRowid!=bRowid - || memcmp(abPK, pTab->abPK, nCol) - )){ - rc = SQLITE_SCHEMA; + rc = sessionReinitTable(pSession, pTab); + if( rc==SQLITE_OK && pTab->nCol!=nOldCol ){ + rc = sessionUpdateChanges(pSession, pTab); } /* Write a table header */ @@ -2762,8 +3012,8 @@ static int sessionGenerateChangeset( /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ - rc = sessionSelectStmt( - db, 0, pSession->zDb, zName, bRowid, nCol, azCol, abPK, &pSel + rc = sessionSelectStmt(db, 0, pSession->zDb, + zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel ); } @@ -2772,22 +3022,22 @@ static int sessionGenerateChangeset( SessionChange *p; /* Used to iterate through changes */ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ - rc = sessionSelectBind(pSel, nCol, abPK, p); + rc = sessionSelectBind(pSel, pTab->nCol, pTab->abPK, p); if( rc!=SQLITE_OK ) continue; if( sqlite3_step(pSel)==SQLITE_ROW ){ if( p->op==SQLITE_INSERT ){ int iCol; sessionAppendByte(&buf, SQLITE_INSERT, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); - for(iCol=0; iColnCol; iCol++){ sessionAppendCol(&buf, pSel, iCol, &rc); } }else{ - assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */ - rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK); + assert( pTab->abPK!=0 ); + rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, pTab->abPK); } }else if( p->op!=SQLITE_INSERT ){ - rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK); + rc = sessionAppendDelete(&buf, bPatchset, p, pTab->nCol,pTab->abPK); } if( rc==SQLITE_OK ){ rc = sqlite3_reset(pSel); @@ -2812,7 +3062,6 @@ static int sessionGenerateChangeset( if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } - sqlite3_free((char*)azCol); /* cast works around VC++ bug */ } } @@ -4941,7 +5190,7 @@ static int sessionChangesetApply( sqlite3changeset_pk(pIter, &abPK, 0); rc = sessionTableInfo(0, db, "main", zNew, - &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK, &sApply.bRowid + &sApply.nCol, &zTab, &sApply.azCol, 0, &sApply.abPK, &sApply.bRowid ); if( rc!=SQLITE_OK ) break; for(i=0; iflags & SQLITE_FkNoAction; + + if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ + db->flags |= ((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } + if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags ); } + + if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ + assert( db->flags & SQLITE_FkNoAction ); + db->flags &= ~((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } return rc; } @@ -5165,6 +5427,9 @@ struct sqlite3_changegroup { int rc; /* Error code */ int bPatch; /* True to accumulate patchsets */ SessionTable *pList; /* List of tables in current patch */ + + sqlite3 *db; /* Configured by changegroup_schema() */ + char *zDb; /* Configured by changegroup_schema() */ }; /* @@ -5350,6 +5615,114 @@ static int sessionChangeMerge( return rc; } +/* +** Check if a changeset entry with nCol columns and the PK array passed +** as the final argument to this function is compatible with SessionTable +** pTab. If so, return 1. Otherwise, if they are incompatible in some way, +** return 0. +*/ +static int sessionChangesetCheckCompat( + SessionTable *pTab, + int nCol, + u8 *abPK +){ + if( pTab->azCol && nColnCol ){ + int ii; + for(ii=0; iinCol; ii++){ + u8 bPK = (ii < nCol) ? abPK[ii] : 0; + if( pTab->abPK[ii]!=bPK ) return 0; + } + return 1; + } + return (pTab->nCol==nCol && 0==memcmp(abPK, pTab->abPK, nCol)); +} + +static int sessionChangesetExtendRecord( + sqlite3_changegroup *pGrp, + SessionTable *pTab, + int nCol, + int op, + const u8 *aRec, + int nRec, + SessionBuffer *pOut +){ + int rc = SQLITE_OK; + int ii = 0; + + assert( pTab->azCol ); + assert( nColnCol ); + + pOut->nBuf = 0; + if( op==SQLITE_INSERT || (op==SQLITE_DELETE && pGrp->bPatch==0) ){ + /* Append the missing default column values to the record. */ + sessionAppendBlob(pOut, aRec, nRec, &rc); + if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ + rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); + } + for(ii=nCol; rc==SQLITE_OK && iinCol; ii++){ + int eType = sqlite3_column_type(pTab->pDfltStmt, ii); + sessionAppendByte(pOut, eType, &rc); + switch( eType ){ + case SQLITE_FLOAT: + case SQLITE_INTEGER: { + i64 iVal; + if( eType==SQLITE_INTEGER ){ + iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); + }else{ + double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii); + memcpy(&iVal, &rVal, sizeof(i64)); + } + if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ + sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); + } + break; + } + + case SQLITE_BLOB: + case SQLITE_TEXT: { + int n = sqlite3_column_bytes(pTab->pDfltStmt, ii); + sessionAppendVarint(pOut, n, &rc); + if( eType==SQLITE_TEXT ){ + const u8 *z = (const u8*)sqlite3_column_text(pTab->pDfltStmt, ii); + sessionAppendBlob(pOut, z, n, &rc); + }else{ + const u8 *z = (const u8*)sqlite3_column_blob(pTab->pDfltStmt, ii); + sessionAppendBlob(pOut, z, n, &rc); + } + break; + } + + default: + assert( eType==SQLITE_NULL ); + break; + } + } + }else if( op==SQLITE_UPDATE ){ + /* Append missing "undefined" entries to the old.* record. And, if this + ** is an UPDATE, to the new.* record as well. */ + int iOff = 0; + if( pGrp->bPatch==0 ){ + for(ii=0; iinCol-nCol); ii++){ + sessionAppendByte(pOut, 0x00, &rc); + } + } + + sessionAppendBlob(pOut, &aRec[iOff], nRec-iOff, &rc); + for(ii=0; ii<(pTab->nCol-nCol); ii++){ + sessionAppendByte(pOut, 0x00, &rc); + } + }else{ + assert( op==SQLITE_DELETE && pGrp->bPatch ); + sessionAppendBlob(pOut, aRec, nRec, &rc); + } + + return rc; +} + /* ** Add all changes in the changeset traversed by the iterator passed as ** the first argument to the changegroup hash tables. @@ -5363,6 +5736,7 @@ static int sessionChangesetToHash( int nRec; int rc = SQLITE_OK; SessionTable *pTab = 0; + SessionBuffer rec = {0, 0, 0}; while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ const char *zNew; @@ -5374,6 +5748,9 @@ static int sessionChangesetToHash( SessionChange *pExist = 0; SessionChange **pp; + /* Ensure that only changesets, or only patchsets, but not a mixture + ** of both, are being combined. It is an error to try to combine a + ** changeset and a patchset. */ if( pGrp->pList==0 ){ pGrp->bPatch = pIter->bPatchset; }else if( pIter->bPatchset!=pGrp->bPatch ){ @@ -5406,18 +5783,38 @@ static int sessionChangesetToHash( pTab->zName = (char*)&pTab->abPK[nCol]; memcpy(pTab->zName, zNew, nNew+1); + if( pGrp->db ){ + pTab->nCol = 0; + rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); + if( rc ){ + assert( pTab->azCol==0 ); + sqlite3_free(pTab); + break; + } + } + /* The new object must be linked on to the end of the list, not ** simply added to the start of it. This is to ensure that the ** tables within the output of sqlite3changegroup_output() are in ** the right order. */ for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); *ppTab = pTab; - }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ + } + + if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ rc = SQLITE_SCHEMA; break; } } + if( nColnCol ){ + assert( pGrp->db ); + rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec); + if( rc ) break; + aRec = rec.aBuf; + nRec = rec.nBuf; + } + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; @@ -5455,6 +5852,7 @@ static int sessionChangesetToHash( } } + sqlite3_free(rec.aBuf); if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } @@ -5541,6 +5939,31 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp){ return rc; } +/* +** Provide a database schema to the changegroup object. +*/ +int sqlite3changegroup_schema( + sqlite3_changegroup *pGrp, + sqlite3 *db, + const char *zDb +){ + int rc = SQLITE_OK; + + if( pGrp->pList || pGrp->db ){ + /* Cannot add a schema after one or more calls to sqlite3changegroup_add(), + ** or after sqlite3changegroup_schema() has already been called. */ + rc = SQLITE_MISUSE; + }else{ + pGrp->zDb = sqlite3_mprintf("%s", zDb); + if( pGrp->zDb==0 ){ + rc = SQLITE_NOMEM; + }else{ + pGrp->db = db; + } + } + return rc; +} + /* ** Add the changeset currently stored in buffer pData, size nData bytes, ** to changeset-group p. @@ -5604,6 +6027,7 @@ int sqlite3changegroup_output_strm( */ void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ + sqlite3_free(pGrp->zDb); sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp); } diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 1ea90dce47..160ea8786b 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -884,6 +884,18 @@ int sqlite3changeset_concat( ); +/* +** CAPI3REF: Upgrade the Schema of a Changeset/Patchset +*/ +int sqlite3changeset_upgrade( + sqlite3 *db, + const char *zDb, + int nIn, const void *pIn, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + + + /* ** CAPI3REF: Changegroup Handle ** @@ -930,6 +942,38 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; */ int sqlite3changegroup_new(sqlite3_changegroup **pp); +/* +** CAPI3REF: Add a Schema to a Changegroup +** METHOD: sqlite3_changegroup_schema +** +** This method may be used to optionally enforce the rule that the changesets +** added to the changegroup handle must match the schema of database zDb +** ("main", "temp", or the name of an attached database). If +** sqlite3changegroup_add() is called to add a changeset that is not compatible +** with the configured schema, SQLITE_SCHEMA is returned and the changegroup +** object is left in an undefined state. +** +** A changeset schema is considered compatible with the database schema in +** the same way as for sqlite3changeset_apply(). Specifically, for each +** table in the changeset, there exists a database table with: +** +**

    +**
  • The name identified by the changeset, and +**
  • at least as many columns as recorded in the changeset, and +**
  • the primary key columns in the same position as recorded in +** the changeset. +**
+** +** The output of the changegroup object always has the same schema as the +** database nominated using this function. In cases where changesets passed +** to sqlite3changegroup_add() have fewer columns than the corresponding table +** in the database schema, these are filled in using the default column +** values from the database schema. This makes it possible to combined +** changesets that have different numbers of columns for a single table +** within a changegroup, provided that they are otherwise compatible. +*/ +int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); + /* ** CAPI3REF: Add A Changeset To A Changegroup ** METHOD: sqlite3_changegroup @@ -998,13 +1042,18 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp); ** If the new changeset contains changes to a table that is already present ** in the changegroup, then the number of columns and the position of the ** primary key columns for the table must be consistent. If this is not the -** case, this function fails with SQLITE_SCHEMA. If the input changeset -** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is -** returned. Or, if an out-of-memory condition occurs during processing, this -** function returns SQLITE_NOMEM. In all cases, if an error occurs the state -** of the final contents of the changegroup is undefined. +** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup +** object has been configured with a database schema using the +** sqlite3changegroup_schema() API, then it is possible to combine changesets +** with different numbers of columns for a single table, provided that +** they are otherwise compatible. ** -** If no error occurs, SQLITE_OK is returned. +** If the input changeset appears to be corrupt and the corruption is +** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition +** occurs during processing, this function returns SQLITE_NOMEM. +** +** In all cases, if an error occurs the state of the final contents of the +** changegroup is undefined. If no error occurs, SQLITE_OK is returned. */ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); @@ -1269,10 +1318,17 @@ int sqlite3changeset_apply_v2( **
  • an insert change if all fields of the conflicting row match ** the row being inserted. ** +** +**
    SQLITE_CHANGESETAPPLY_FKNOACTION
    +** If this flag it set, then all foreign key constraints in the target +** database behave as if they were declared with "ON UPDATE NO ACTION ON +** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL +** or SET DEFAULT. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 +#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 /* ** CAPI3REF: Constants Passed To The Conflict Handler diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 0836238b5d..7931f08526 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -812,9 +812,12 @@ static int SQLITE_TCLAPI testSqlite3changesetApply( while( objc>1 ){ const char *z1 = Tcl_GetString(objv[1]); int n = strlen(z1); - if( n>1 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){ + if( n>3 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){ flags |= SQLITE_CHANGESETAPPLY_NOSAVEPOINT; } + else if( n>3 && n<=9 && 0==sqlite3_strnicmp("-noaction", z1, n) ){ + flags |= SQLITE_CHANGESETAPPLY_FKNOACTION; + } else if( n>2 && n<=7 && 0==sqlite3_strnicmp("-invert", z1, n) ){ flags |= SQLITE_CHANGESETAPPLY_INVERT; } @@ -1452,12 +1455,144 @@ static int SQLITE_TCLAPI test_sqlite3session_config( return TCL_OK; } +typedef struct TestChangegroup TestChangegroup; +struct TestChangegroup { + sqlite3_changegroup *pGrp; +}; + +/* +** Destructor for Tcl changegroup command object. +*/ +static void test_changegroup_del(void *clientData){ + TestChangegroup *pGrp = (TestChangegroup*)clientData; + sqlite3changegroup_delete(pGrp->pGrp); + ckfree(pGrp); +} + +/* +** Tclcmd: $changegroup schema DB DBNAME +** Tclcmd: $changegroup add CHANGESET +** Tclcmd: $changegroup output +** Tclcmd: $changegroup delete +*/ +static int SQLITE_TCLAPI test_changegroup_cmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + TestChangegroup *p = (TestChangegroup*)clientData; + static struct ChangegroupCmd { + const char *zSub; + int nArg; + const char *zMsg; + int iSub; + } aSub[] = { + { "schema", 2, "DB DBNAME", }, /* 0 */ + { "add", 1, "CHANGESET", }, /* 1 */ + { "output", 0, "", }, /* 2 */ + { "delete", 0, "", }, /* 3 */ + { 0 } + }; + int rc = TCL_OK; + int iSub = 0; + + if( objc<2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); + return TCL_ERROR; + } + rc = Tcl_GetIndexFromObjStruct(interp, + objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub + ); + if( rc!=TCL_OK ) return rc; + if( objc!=2+aSub[iSub].nArg ){ + Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg); + return TCL_ERROR; + } + + switch( iSub ){ + case 0: { /* schema */ + sqlite3 *db = 0; + const char *zDb = Tcl_GetString(objv[3]); + if( dbHandleFromObj(interp, objv[2], &db) ){ + return TCL_ERROR; + } + rc = sqlite3changegroup_schema(p->pGrp, db, zDb); + if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0); + break; + }; + + case 1: { /* add */ + int nByte = 0; + const u8 *aByte = Tcl_GetByteArrayFromObj(objv[2], &nByte); + rc = sqlite3changegroup_add(p->pGrp, nByte, (void*)aByte); + if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0); + break; + }; + + case 2: { /* output */ + int nByte = 0; + u8 *aByte = 0; + rc = sqlite3changegroup_output(p->pGrp, &nByte, (void**)&aByte); + if( rc!=SQLITE_OK ){ + rc = test_session_error(interp, rc, 0); + }else{ + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aByte, nByte)); + } + sqlite3_free(aByte); + break; + }; + + default: { /* delete */ + assert( iSub==3 ); + Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); + break; + } + } + + return rc; +} + +/* +** Tclcmd: sqlite3changegroup CMD +*/ +static int SQLITE_TCLAPI test_sqlite3changegroup( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; /* sqlite3changegroup_new() return code */ + TestChangegroup *p; /* New wrapper object */ + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "CMD"); + return TCL_ERROR; + } + + p = (TestChangegroup*)ckalloc(sizeof(TestChangegroup)); + memset(p, 0, sizeof(TestChangegroup)); + rc = sqlite3changegroup_new(&p->pGrp); + if( rc!=SQLITE_OK ){ + ckfree((char*)p); + return test_session_error(interp, rc, 0); + } + + Tcl_CreateObjCommand( + interp, Tcl_GetString(objv[1]), test_changegroup_cmd, (ClientData)p, + test_changegroup_del + ); + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; +} + int TestSession_Init(Tcl_Interp *interp){ struct Cmd { const char *zCmd; Tcl_ObjCmdProc *xProc; } aCmd[] = { { "sqlite3session", test_sqlite3session }, + { "sqlite3changegroup", test_sqlite3changegroup }, { "sqlite3session_foreach", test_sqlite3session_foreach }, { "sqlite3changeset_invert", test_sqlite3changeset_invert }, { "sqlite3changeset_concat", test_sqlite3changeset_concat }, diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js index 60050461c7..f23a02366b 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.js @@ -888,9 +888,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ consistency with non-special-case wrappings. */ const __dbArgcMismatch = (pDb,f,n)=>{ - return sqlite3.util.sqlite3_wasm_db_error(pDb, capi.SQLITE_MISUSE, - f+"() requires "+n+" argument"+ - (1===n?"":'s')+"."); + return util.sqlite3_wasm_db_error(pDb, capi.SQLITE_MISUSE, + f+"() requires "+n+" argument"+ + (1===n?"":'s')+"."); }; /** Code duplication reducer for functions which take an encoding diff --git a/ext/wasm/api/sqlite3-api-worker1.js b/ext/wasm/api/sqlite3-api-worker1.js index 9a386c13e7..29f7d2be63 100644 --- a/ext/wasm/api/sqlite3-api-worker1.js +++ b/ext/wasm/api/sqlite3-api-worker1.js @@ -333,7 +333,6 @@ sqlite3.initWorker1API = function(){ if(!(globalThis.WorkerGlobalScope instanceof Function)){ toss("initWorker1API() must be run from a Worker thread."); } - const self = this.self; const sqlite3 = this.sqlite3 || toss("Missing this.sqlite3 object."); const DB = sqlite3.oo1.DB; @@ -657,5 +656,5 @@ sqlite3.initWorker1API = function(){ }, wState.xfer); }; globalThis.postMessage({type:'sqlite3-api',result:'worker1-ready'}); -}.bind({self, sqlite3}); +}.bind({sqlite3}); }); diff --git a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js index 327b6a95ad..870073cc09 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js @@ -155,8 +155,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ pool.deletePath(file.path); } }catch(e){ - pool.storeErr(e); - return capi.SQLITE_IOERR; + return pool.storeErr(e, capi.SQLITE_IOERR); } } return 0; @@ -200,8 +199,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } return 0; }catch(e){ - pool.storeErr(e); - return capi.SQLITE_IOERR; + return pool.storeErr(e, capi.SQLITE_IOERR); } }, xSectorSize: function(pFile){ @@ -217,8 +215,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ file.sah.flush(); return 0; }catch(e){ - pool.storeErr(e); - return capi.SQLITE_IOERR; + return pool.storeErr(e, capi.SQLITE_IOERR); } }, xTruncate: function(pFile,sz64){ @@ -231,8 +228,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ file.sah.truncate(HEADER_OFFSET_DATA + Number(sz64)); return 0; }catch(e){ - pool.storeErr(e); - return capi.SQLITE_IOERR; + return pool.storeErr(e, capi.SQLITE_IOERR); } }, xUnlock: function(pFile,lockType){ @@ -252,10 +248,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.heap8u().subarray(pSrc, pSrc+n), { at: HEADER_OFFSET_DATA + Number(offset64) } ); - return nBytes === n ? 0 : capi.SQLITE_IOERR; + return n===nBytes ? 0 : toss("Unknown write() failure."); }catch(e){ - pool.storeErr(e); - return capi.SQLITE_IOERR; + return pool.storeErr(e, capi.SQLITE_IOERR); } } }/*ioMethods*/; @@ -314,8 +309,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }, xGetLastError: function(pVfs,nOut,pOut){ const pool = getPoolForVfs(pVfs); - pool.log(`xGetLastError ${nOut}`); const e = pool.popErr(); + pool.log(`xGetLastError ${nOut} e =`,e); if(e){ const scope = wasm.scopedAllocPush(); try{ @@ -328,7 +323,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.scopedAllocPop(scope); } } - return 0; + return e ? (e.sqlite3Rc || capi.SQLITE_IOERR) : 0; }, //xSleep is optionally defined below xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){ @@ -762,12 +757,20 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } /** - Sets e as this object's current error. Pass a falsy - (or no) value to clear it. + Sets e (an Error object) as this object's current error. Pass a + falsy (or no) value to clear it. If code is truthy it is + assumed to be an SQLITE_xxx result code, defaulting to + SQLITE_IOERR if code is falsy. + + Returns the 2nd argument. */ - storeErr(e){ - if(e) this.error(e); - return this.$error = e; + storeErr(e,code){ + if(e){ + e.sqlite3Rc = code || capi.SQLITE_IOERR; + this.error(e); + } + this.$error = e; + return code; } /** Pops this object's Error object and returns @@ -900,6 +903,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*force db out of WAL mode*/); }catch(e){ this.setAssociatedPath(sah, '', 0); + throw e; } this.setAssociatedPath(sah, name, capi.SQLITE_OPEN_MAIN_DB); return nWrote; diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index db77010d95..88a679c518 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -84,6 +84,14 @@ /**********************************************************************/ /* SQLITE_ENABLE_... */ +/* +** Unconditionally enable API_ARMOR in the WASM build. It ensures that +** public APIs behave predictable in the face of passing illegal NULLs +** or ranges which might otherwise invoke undefined behavior. +*/ +#undef SQLITE_ENABLE_API_ARMOR +#define SQLITE_ENABLE_API_ARMOR 1 + #ifndef SQLITE_ENABLE_BYTECODE_VTAB # define SQLITE_ENABLE_BYTECODE_VTAB 1 #endif diff --git a/ext/wasm/api/sqlite3-worker1.c-pp.js b/ext/wasm/api/sqlite3-worker1.c-pp.js index f260422309..220722ffe1 100644 --- a/ext/wasm/api/sqlite3-worker1.c-pp.js +++ b/ext/wasm/api/sqlite3-worker1.c-pp.js @@ -37,7 +37,7 @@ import {default as sqlite3InitModule} from './sqlite3-bundler-friendly.mjs'; "use strict"; { const urlParams = globalThis.location - ? new URL(self.location.href).searchParams + ? new URL(globalThis.location.href).searchParams : new URLSearchParams(); let theJs = 'sqlite3.js'; if(urlParams.has('sqlite3.dir')){ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index f694598eab..92d763f1ba 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -3253,4 +3253,3 @@ globalThis.sqlite3InitModule = sqlite3InitModule; TestUtil.runTests(sqlite3); }); })(self); - diff --git a/manifest b/manifest index 6cf5f1135d..4abce30cc7 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Cause\ssqlite3_exper_new()\sto\sreplicate\sUDFs\sand\scustom\scollations\searly\senough\sto\sappear\sin\svirtual\scolumn\sexpressions\sduring\sschema\scopy.\s[forum:/forumpost/e030aa4b3a|forum\spost\se030aa4b3a] -D 2023-09-25T00:39:43.862 +C Clear\ssome\spicky\swarnings,\ssync\sw/trunk. +D 2023-10-23T01:55:35.001 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 3150cc65edc3643ab243282b404d242b19b447365bfd7f3eda73d71349424f89 +F Makefile.in 2ea4105b72561483befe0a18a37f94ca3adbc2324bad3770f99555d95fb9b0ea F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 -F Makefile.msc f926abe4737ffa3303aeb67d8ea74857f4038754a95605c332be1c9dbf8b96c7 +F Makefile.msc e5c93ed28696ab0065e72ce352c7ec766c8b9e91f93fd1bb15000c6e35dfe58c F README.md 963d30019abf0cc06b263cd2824bce022893f3f93a531758f6f04ff2194a16a8 F VERSION 4c09b629c03b8ae32317cb336a32f3aa3252841d6dcd51184cecc4278d08f21e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.msc 3248809e70cf439a13e9faf82a4e12cbdb7b042006300ac67175fc5125b5c031 +F autoconf/Makefile.msc 3dfe7dc4677569256724e4988db59521f10b1d8b8fba393ea8a255eb038b9825 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56 F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277 @@ -33,8 +33,8 @@ F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea0034 F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 060cfb6cea3bd34b9c6fd573791c5f30961dd2cafeccc8940b6f3404b884bdc8 x -F configure.ac 64b353b3f56b432e77041d86c83c86782a1df96af28fe9b4d845b00d042137e0 +F configure 1d9cbcb416cb5387b3f750ae6db63cfedb703a2e46bf8ca61daecff31d208252 x +F configure.ac de31fea7d975bb7ebafbe0e2190a855cc80d48558bf0c9a6578a1836daf1cd3a F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/compile-for-windows.md c52f2903f1cb11b2308798feecca2e44701b037b78f467a538ac5c46c28ee250 @@ -53,32 +53,32 @@ F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a4980828 F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 F ext/expert/expert1.test 77eaa3efd906e245a8948cb496174724b867b43b5c0fd9bb4fe7f77f27c64517 -F ext/expert/sqlite3expert.c 1803b13cbe118f01486479f557e5403459802a69d90886d7f0465f78f1f61719 +F ext/expert/sqlite3expert.c 4255c8e53da9f777ba9222897a5e4b33a750564d61a66d72fba9c2bdc392ccf5 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 4095c97f2960f508bd34fc06d40f61d54e2ad09e7fbab75dc0114f57ebb6040d +F ext/fts3/fts3.c c409b5f9211dbe9336210435ef3bc936e54c4f2ad9b92c9a7cd5442cbbbf1411 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h e573c6d881f7238d77cc3fd2396cbb9b2fe13efef7d2ad295a155151c4e7efbd -F ext/fts3/fts3_aux.c f0dc9bd98582615b7750218899bd0c729879b6bbf94d1be57ca1833ff49afc6f +F ext/fts3/fts3Int.h be688580701d41340de73384e3acc8c55be12a438583207444bd5e20f9ef426c +F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 F ext/fts3/fts3_expr.c 903bfb9433109fffb10e910d7066c49cbf8eeae316adc93f0499c4da7dfc932a F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8 F ext/fts3/fts3_snippet.c 4d6523e3eddeb7b46e7a82b3476a0a86a0c04821e0e2b8dd40f45ee28057cb13 -F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1 +F ext/fts3/fts3_term.c 845f0e2456b1be42f7f1bec1da1dfc05bc347531eff90775ffc6698902c281de F ext/fts3/fts3_test.c d8d7b2734f894e8a489987447658e374cdd3a3bc8575c401decf1911cb7c6454 -F ext/fts3/fts3_tokenize_vtab.c a95feda3590f3c3e17672fe35b67ea6112471aeea4c07ef7744a6606b66549aa +F ext/fts3/fts3_tokenize_vtab.c 7fd9ef364f257b97218b9c331f2378e307375c592f70fd541f714e747d944962 F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154 F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226 F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c b28f4cde90ed560245ecb76a882b45aa62da16ff6f61e9884eae5c7c5eff16ea +F ext/fts3/fts3_write.c 16df5ea9ff3634821003ac71a0275e3af030517b8768680062f425a347aab5f0 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674 @@ -94,16 +94,16 @@ F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b7292 F ext/fts5/fts5_config.c 054359543566cbff1ba65a188330660a5457299513ac71c53b3a07d934c7b081 F ext/fts5/fts5_expr.c bd3b81ce669c4104e34ffe66570af1999a317b142c15fccb112de9fb0caa57a6 F ext/fts5/fts5_hash.c 65e7707bc8774706574346d18c20218facf87de3599b995963c3e6d6809f203d -F ext/fts5/fts5_index.c a86bcd5637625ce1037649d55974ab8da1fa8d1375cb334aae47ef376642e93b -F ext/fts5/fts5_main.c 799ec88d2309055f6406bddb0bd6ed80148c5da5eb14594c3c5309a6e944d489 -F ext/fts5/fts5_storage.c 3c9b41fce41b6410f2e8f82eb035c6a29b2560483f773e6dc98cf3cb2e4ddbb5 +F ext/fts5/fts5_index.c 730c9c32ada18ce1eb7ff847b36507f4b005d88d47af7b47db521e695a8ea4c7 +F ext/fts5/fts5_main.c 1ce6c8f446afbaaf22f4e1ccc0ec46d653168545b89a53bdbba0beddda820bec +F ext/fts5/fts5_storage.c 5d10b9bdcce5b90656cad13c7d12ad4148677d4b9e3fca0481fca56d6601426d F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee -F ext/fts5/fts5_test_tok.c a2bed8edb25f6432e8cdb62aad5916935c19dba8dac2b8324950cfff397e25ff +F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_tokenize.c 5e251efb0f1af99a25ed50010ba6b1ad1250aca5921af1988fdcabe5ebc3cb43 F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 -F ext/fts5/fts5_vocab.c 12138e84616b56218532e3e8feb1d3e0e7ae845e33408dbe911df520424dc9d6 +F ext/fts5/fts5_vocab.c aed56169ae5c1aa9b8189c779ffeef04ed516d3c712c06914e6d91a6759f4e4a F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl a9de9c2209cc4e7ae3c753e783504e67206c6c1467d08f209cd0c5923d3e8d8b @@ -167,6 +167,7 @@ F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05c F ext/fts5/test/fts5faultD.test e7ed7895abfe6bc98a5e853826f6b74956e7ba7f594f1860bbf9e504b9647996 F ext/fts5/test/fts5faultE.test 844586ce71dab4be85bb86880e87b624d089f851654cd22e4710c77eb8ce7075 F ext/fts5/test/fts5faultF.test 4abef99f86e99d9f0c6460dd68c586a766b6b9f1f660ada55bf2e8266bd1bbc1 +F ext/fts5/test/fts5faultG.test 340e59d2c2c1c7c379224f3968ee8d09b0f64bf56c5194217d1ded887b9d47c4 F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079 F ext/fts5/test/fts5full.test e1701a112354e0ff9a1fdffb0c940c576530c33732ee20ac5e8361777070d717 F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e @@ -198,13 +199,13 @@ F ext/fts5/test/fts5rank.test 30f29e278cd7fb8831ba4f082feb74d8eb90c463bf07113ae2 F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7 F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415 F ext/fts5/test/fts5rowid.test b8790ec170a8dc1942a15aef3db926a5f3061b1ff171013003d8297203a20ad6 -F ext/fts5/test/fts5savepoint.test fc02929f238d02a22df4172625704e029f7c1e0e92e332d654375690f8e6e43f +F ext/fts5/test/fts5savepoint.test 050796b24929325cdbbb2fbfe2794816ae95d298e940ae15032200c2f4a73725 F ext/fts5/test/fts5secure.test a02f771742fb2b1b9bdcb4bf523bcf2d0aa1ff597831d40fe3e72aaa6d0ec40f F ext/fts5/test/fts5secure2.test 2e961d7eef939f294c56b5d895cac7f1c3a60b934ee2cfd5e5e620bdf1ba6bbc F ext/fts5/test/fts5secure3.test c7e1080a6912f2a3ac68f2e05b88b72a99de38543509b2bbf427cac5c9c1c610 F ext/fts5/test/fts5secure4.test 0d10a80590c07891478700af7793b232962042677432b9846cf7fc8337b67c97 F ext/fts5/test/fts5secure5.test c07a68ced5951567ac116c22f2d2aafae497e47fe9fcb6a335c22f9c7a4f2c3a -F ext/fts5/test/fts5secure6.test 120feecc8c55b4774f858721e6c62c2094b059ecbcfd7fdc24bde886f55ef6ca +F ext/fts5/test/fts5secure6.test 74bf04733cc523bccca519bb03d3b4e2ed6f6e3db7c59bf6be82c88a0ac857fd F ext/fts5/test/fts5secure7.test fd03d0868d64340a1db8615b02e5508fea409de13910114e4f19eaefc120777a F ext/fts5/test/fts5securefault.test dbca2b6a1c16700017f5051138991b705410889933f2a37c57ae8a23b296b10b F ext/fts5/test/fts5simple.test a298670508c1458b88ce6030440f26a30673931884eb5f4094ac1773b3ba217b @@ -235,61 +236,68 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282 F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 -F ext/jni/GNUmakefile 42e00052401b6dd41c0cdd53b31450606ea37486283abdb038dff9be74bff71e -F ext/jni/README.md 9fceaeb17cecdc5d699dfc83c0cbc3a03fdb3b86bf676381894166c73375ee75 +F ext/jni/GNUmakefile 5c3ac326bf3853486ebe0d70819abc790cc65c412182ce4ebd5012b008d9b059 +F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa -F ext/jni/src/c/sqlite3-jni.c e8e0ac79c23a1f31c8c7d070776e6438872e309359bf9105c568b5f146d1761b -F ext/jni/src/c/sqlite3-jni.h c934b646b62c0fd13dfceea7a54d8fc0d1274d0520d0edc58ad220753f4c4f7d -F ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java 95e88ba04f4aac51ffec65693e878e234088b2f21b387f4e4285c8b72b33e436 -F ext/jni/src/org/sqlite/jni/AggregateFunction.java 7312486bc65fecdb91753c0a4515799194e031f45edbe16a6373cea18f404dc4 -F ext/jni/src/org/sqlite/jni/AuthorizerCallback.java e6135be32f12bf140bffa39be7fd1a45ad83b2661ed49c08dbde04c8485feb38 -F ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java 5e4a75611c026730289d776469d6122cb2699d6970af5f53fe85e74d49930476 -F ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java d316373b12b3bf1a421f1f7eed08128fa8dd52bb98617ba28c161aaabd71d1ee -F ext/jni/src/org/sqlite/jni/CallbackProxy.java 064a8a00e4c63cc501c30504f93ca996d422c5f010067f969b2d0a10f0868153 -F ext/jni/src/org/sqlite/jni/CollationCallback.java df327348e1a34ee65210208d694d690e5ee0bfe901410122e07caf6c98b2b7c8 -F ext/jni/src/org/sqlite/jni/CollationNeededCallback.java 07df5fa161a0b81154295258037f662e7c372735c2899c76e81cb3abd9fd3b39 -F ext/jni/src/org/sqlite/jni/CommitHookCallback.java 77cf8bb4f5548113e9792978f3f8a454614f420fa0ad73939421cbff4e7776f2 -F ext/jni/src/org/sqlite/jni/ConfigLogCallback.java 636ed6b89ed03f15bc2a6f6f47bf7853b8328e5a8269e52e80630708efa703a6 -F ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java e3656909eab7ed0f7e457c5b82df160ca22dd5e954c0a306ec1fca61b0d266b4 -F ext/jni/src/org/sqlite/jni/NativePointerHolder.java 564087036449a16df148dcf0a067408bd251170bf23286c655f46b5f973e8b2d -F ext/jni/src/org/sqlite/jni/OutputPointer.java 2f57c05672ddc9b38e3f8eed11759896cf0bf01107ffd24d5182b99f6e7254b6 -F ext/jni/src/org/sqlite/jni/PrepareMultiCallback.java 878ed9cc8000def1a4e6d7113d52bba6fce0aa6733b4eb216d68dfbe096776ac -F ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java eccaed8dc9c6289f07ef3fc109891c6be1e7cc6c88723d90174b68706fc21cda -F ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java 7b9ff2218129ece98ba60c57eeedcd8447e9e3b6e5d0f5e5d3eb0f0c5037d48d -F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7ce7797f2c6c7fca2004ff12ce20f86 -F ext/jni/src/org/sqlite/jni/RollbackHookCallback.java d12352c0e22840de484ffa9b11ed5058bb0daca2e9f218055d3c54c947a273c4 -F ext/jni/src/org/sqlite/jni/SQLFunction.java 544a875d33fd160467d82e2397ac33157b29971d715a821a4fad3c899113ee8c -F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 42862db7c904f4dc90c16faeadf09874a9bab92acd321aed265651575ae596e3 -F ext/jni/src/org/sqlite/jni/ScalarFunction.java 6d387bb499fbe3bc13c53315335233dbf6a0c711e8fa7c521683219b041c614c -F ext/jni/src/org/sqlite/jni/TableColumnMetadata.java 54511b4297fa28dcb3f49b24035e34ced10e3fd44fd0e458e784f4d6b0096dab -F ext/jni/src/org/sqlite/jni/Tester1.java 30627199744e2c80b03d8d2ac439b2270a7050bedaa6d4b293cd08a2817741f4 -F ext/jni/src/org/sqlite/jni/TraceV2Callback.java beb0b064c1a5f8bfe585a324ed39a4e33edbe379a3fc60f1401661620d3ca7c0 -F ext/jni/src/org/sqlite/jni/UpdateHookCallback.java 8376f4a931f2d5612b295c003c9515ba933ee76d8f95610e89c339727376e36c -F ext/jni/src/org/sqlite/jni/WindowFunction.java 488980f4dbb6bdd7067d6cb9c43e4075475e51c54d9b74a5834422654b126246 -F ext/jni/src/org/sqlite/jni/XDestroyCallback.java 50c5ca124ef6c6b735a7e136e7a23a557be367e61b56d4aab5777a614ab46cc2 -F ext/jni/src/org/sqlite/jni/annotation/Canonical.java 2767daa5b3893b96729db80a0f8234d379d266d1b2c21400a057864b538a0ea5 -F ext/jni/src/org/sqlite/jni/annotation/NotNull.java d9b32956cb9fb11d1f8a562e5df70d0599820265285120c63858294dbe2b7711 -F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 6f962a98c9a5c6e9d21c50ae8716b16bdfdc934a191608cbb7e12ea588ddb6af -F ext/jni/src/org/sqlite/jni/annotation/package-info.java f66bfb621c6494e67c03ed38a9e26a3bd6af99b9f9f6ef79556bcec30a025a22 +F ext/jni/src/c/sqlite3-jni.c 6f6df9657989e9ca2cfdcc2fe9a71c279de56d5c941adfd09a0f24256de35c8f +F ext/jni/src/c/sqlite3-jni.h b4c413a0d0c734683da1049cfcf89e35ae2719759d0656ec0f8c57188f18cab8 +F ext/jni/src/org/sqlite/jni/annotation/NotNull.java a99341e88154e70447596b1af6a27c586317df41a7e0f246fd41370cd7b723b2 +F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 0b1879852707f752512d4db9d7edd0d8db2f0c2612316ce1c832715e012ff6ba +F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca +F ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java 1afa90d3f236f79cc7fcd2497e111992644f7596fbc8e8bcf7f1908ae00acd6c w ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java +F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java bc29e986c866c2ddbbb9f935f5b7264c1c1026864e50a4a735192864f75e37c0 w ext/jni/src/org/sqlite/jni/AggregateFunction.java +F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java 7ed409d5449684616cc924534e22ff6b07d361f12ad904b69ecb10e0568a8013 w ext/jni/src/org/sqlite/jni/AuthorizerCallback.java +F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759 w ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java +F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca w ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java +F ext/jni/src/org/sqlite/jni/capi/CApi.java bccb442ca81cd4decb1adae99006a60b7a9f54e5153842e738c01104e97d1de0 w ext/jni/src/org/sqlite/jni/SQLite3Jni.java +F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 0bfd6e56e8265c2f05c9207665707285534d78f8466ef0e0430c65677f00943d w ext/jni/src/org/sqlite/jni/CallbackProxy.java +F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a w ext/jni/src/org/sqlite/jni/CollationCallback.java +F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java f81cf10b79c52f9b2e9247d523d29ae48863935f60420eae35f257c38c80ce95 w ext/jni/src/org/sqlite/jni/CollationNeededCallback.java +F ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java 29c002f3c638cc80f7db1594564a262d1beb32637824c3dca2d60a224d1f71d7 w ext/jni/src/org/sqlite/jni/CommitHookCallback.java +F ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java b995ca412f59b631803b93aa5b3684fce62e335d1e123207084c054abfd488d4 w ext/jni/src/org/sqlite/jni/ConfigLogCallback.java +F ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java 701f2e4d8bdeb27cfbeeb56315d15b13d8752b0fdbca705f31bd4366c58d8a33 w ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java +F ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java b7036dcb1ef1b39f1f36ac605dde0ff1a24a9a01ade6aa1a605039443e089a61 w ext/jni/src/org/sqlite/jni/NativePointerHolder.java +F ext/jni/src/org/sqlite/jni/capi/OutputPointer.java 68f60aec7aeb5cd4e5fb83449037f668c63cb99f682ee1036cc226d0cbd909b9 w ext/jni/src/org/sqlite/jni/OutputPointer.java +F ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java aca8f9fa72e3b6602bc9a7dd3ae9f5b2808103fbbee9b2749dc96c19cdc261a1 w ext/jni/src/org/sqlite/jni/PrepareMultiCallback.java +F ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java 819d938e26208adde17ca4b7ddde1d8cd6915b6ab7b708249a9787beca6bd6b6 w ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java +F ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java 01bc0c238eed2d5f93c73522cb7849a445cc9098c2ed1e78248fa20ed1cfde5b w ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java +F ext/jni/src/org/sqlite/jni/capi/ResultCode.java 8141171f1bcf9f46eef303b9d3c5dc2537a25ad1628f3638398d8a60cacefa7f w ext/jni/src/org/sqlite/jni/ResultCode.java +F ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java 105e324d09c207100485e7667ad172e64322c62426bb49b547e9b0dc9c33f5f0 w ext/jni/src/org/sqlite/jni/RollbackHookCallback.java +F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java fef556adbc3624292423083a648bdf97fa8a4f6b3b6577c9660dd7bd6a6d3c4a w ext/jni/src/org/sqlite/jni/SQLFunction.java +F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 09bee15aa0eedac68d767ae21d9a6a62a31ade59182a3ccbf036d6463d9e30b1 w ext/jni/src/org/sqlite/jni/tester/SQLTester.java +F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615 w ext/jni/src/org/sqlite/jni/ScalarFunction.java +F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff2260daa7ce305ff9b5fafd64153a7a28e9d8f000a815f w ext/jni/src/org/sqlite/jni/TableColumnMetadata.java +F ext/jni/src/org/sqlite/jni/capi/Tester1.java ca195521b6bda3e0cd00e76bb71ec8060d1fab76a2f13b1af9feea40789f44bb w ext/jni/src/org/sqlite/jni/Tester1.java +F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723 w ext/jni/src/org/sqlite/jni/TraceV2Callback.java +F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java 2766b8526bbffc4f1045f70e79f1bc1b1efe1c3e95ca06cdb8a7391032dda3b4 w ext/jni/src/org/sqlite/jni/UpdateHookCallback.java +F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 9f9e151f1da017b706c0ee5f40f4c86b54e773d6ae4339723e0cc85a456251ab +F ext/jni/src/org/sqlite/jni/capi/WindowFunction.java caf4396f91b2567904cf94bc538a069fd62260d975bd037d15a02a890ed1ef9e w ext/jni/src/org/sqlite/jni/WindowFunction.java +F ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java f3abb8dd7381f53ebba909437090caf68200f06717b8a7d6aa96fa3e8133117d w ext/jni/src/org/sqlite/jni/XDestroyCallback.java +F ext/jni/src/org/sqlite/jni/capi/package-info.java 08ff986a65d2be9162442c82d28a65ce431d826f188520717c2ecb1484d0a50e w ext/jni/src/org/sqlite/jni/package-info.java +F ext/jni/src/org/sqlite/jni/capi/sqlite3.java 4010bbebc5bf44e2044e610786088cdee7dc155da2b333c0551492ff1cedf33b w ext/jni/src/org/sqlite/jni/sqlite3.java +F ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java 6742b431cd4d77e8000c1f92ec66265a58414c86bf3b0b5fbcb1164e08477227 w ext/jni/src/org/sqlite/jni/sqlite3_backup.java +F ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java f204ab6ab1263e119fe43730141a00662d80972129a5351dfb11aae5d282df36 w ext/jni/src/org/sqlite/jni/sqlite3_blob.java +F ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java f0ef982009c335c4393ffcb68051809ca1711e4f47bcb8d1d46952f22c01bc22 w ext/jni/src/org/sqlite/jni/sqlite3_context.java +F ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java ff579621e9bd5ffbc6b2ef9f996c12db4df6e0c8cc5697c91273e5fca279fcf8 w ext/jni/src/org/sqlite/jni/sqlite3_stmt.java +F ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java e1d62a257c13504b46d39d5c21c49cf157ad73fda00cc5f34c931aa008c37049 w ext/jni/src/org/sqlite/jni/sqlite3_value.java F ext/jni/src/org/sqlite/jni/fts5/Fts5.java e94681023785f1eff5399f0ddc82f46b035977d350f14838db659236ebdf6b41 -F ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 7058da97059b8e156c17561a47ecd7faa0fc3e2d8c2588b9a28dbff8d06202dd -F ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java b1b23431ece266c3308c1089d4cc3d2762a36ff4ea720196be1bcd75577abb9a -F ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java 2a7f3d76a1206e6a43d4c4ed9609b294d5431cc7d8fb875d8419f76efa6e56dc -F ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java cc9a53846a168a215238af224c31cef0e8379780e36e8a5e743b00c08145cf19 -F ext/jni/src/org/sqlite/jni/fts5/TesterFts5.java 81ec50bb4c5a285177ea8bebe906792886fc733676d0eade76b18fac56057623 +F ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 338637e6e5a2cc385d962b220f3c1f475cc371d12ae43d18ef27327b6e6225f7 +F ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java 7da0fbb5728f7c056a43e6407f13dd0c7c9c445221267786a109b987f5fc8a9d +F ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java 28045042d593a1f1b9b80d54ec77cbf1d8a1bc95e442eceefa9a3a6f56600b0e +F ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java 3c8f677ffb85b8782f865d6fcbc16200b3375d0e3c29ed541a494fde3011bf49 +F ext/jni/src/org/sqlite/jni/fts5/TesterFts5.java eaee4d641229a098eb704b96a45c9a23c6514dc39009d3611e265bab33834deb F ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java 1efd1220ea328a32f2d2a1b16c735864159e929480f71daad4de9d5944839167 -F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java 6071bf76c2c6a0f035b99adc76715b0324f540a441452b4ff6b94d9360a6a83d -F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 1fe0f5692c1d67475d12b067f0469949073446f18c56eba5ee5da6ddd06db9b9 -F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 49e1813743e577636ea22159a9466c8f84e2be88a36e02b0d928432d10b15a0f -F ext/jni/src/org/sqlite/jni/package-info.java a3946db2504de747a1993c4f6e8ce604bec5a8e5a134b292c3b07527bc321a99 -F ext/jni/src/org/sqlite/jni/sqlite3.java 62b1b81935ccf3393472d17cb883dc5ff39c388ec3bc1de547f098a0217158fc -F ext/jni/src/org/sqlite/jni/sqlite3_backup.java d0bb06dd6225e76999ff6b7ab20f2643b1c4d4167431b3a93ea41943e41f094b -F ext/jni/src/org/sqlite/jni/sqlite3_blob.java f28a30134f2e524eb7d5ab87f57f86c90140341a6e8369ee54509ac8bb96fa82 -F ext/jni/src/org/sqlite/jni/sqlite3_context.java 66ca95ce904044263a4aff684abe262d56f73e6b06bca6cf650761d79d7779ad -F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc -F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a -F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 9892797db57c6e01f0c1601b5866474b6c046f0fd6c5b64f411e5815c941040e -F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e +F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java a8e88c3783d21cec51b0748568a96653fead88f8f4953376178d9c7385b197ea +F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 9e2b954d210d572552b28aca523b272fae14bd41e318921b22f65b728d5bf978 +F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 92bdaa3893bd684533004d64ade23d329843f809cd0d0f4f1a2856da6e6b4d90 +F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e w ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md +F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java 5ad99bd74c85f56bbef324d9ec29b4048f4620547c9a80093d8586c3557f9f9a +F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 43c43adfb7866098aadaaca1620028a6ec82d5193149970019b1cce9eb59fb03 +F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 004394eeb944baa56e36cd7ae69ba6d4a52b52db3c49439db16e98270b861421 +F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java a9ddc6a9e8c113168cc67592ae24c0e56d30dd06226eeab012f2761a0889d7bb +F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 1386f7b753134fc12253ce2fbbc448ba8c970567fac01a3356cb672e14408d73 +F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java c24b510ebe801c30533cc62efdf69a4a5e2da9ec4b49f8d403f2060693f060a0 +F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java 7b89a7391f771692c5b83b0a5b86266abe8d59f1c77d7a0eccc9b79f259d79af F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745 F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70 F ext/jni/src/tests/900-001-fts.test bf0ce17a8d082773450e91f2388f5bbb2dfa316d0b676c313c637a91198090f0 @@ -333,36 +341,36 @@ F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678 F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb F ext/lsm1/lsm_unix.c 11e0a5c19d754a4e1d93dfad06de8cc201f10f886b8e61a4c599ed34e334fc24 F ext/lsm1/lsm_varint.c fe134ad7b2db1ecd99b6a155d2f3625cfd497730e227ae18892452e457b73327 -F ext/lsm1/lsm_vtab.c e57aa3eb456bf2b98064014027e097c9402d6dec7b59564ddbfa1c0ead8f96c5 +F ext/lsm1/lsm_vtab.c 0bc7d2702150e9d5513118f23fdb5d7f3642884e6c0dde332da08b016857887a F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1dedaf04a8774a6d8d82 F ext/lsm1/test/lsm1_simple.test a04d08e8661ae6fc53786c67f0bd102c6692f003e859dde03ed9ac3f12e066e5 F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f6078e07335398b0 F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240 -F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358 +F ext/misc/amatch.c 5001711cbecdd57b288cb613386789f3034e5beb58fbe0c79f2b3d643ffd4e03 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824 F ext/misc/base64.c a71b131e50300c654a66c469a25b62874481f3d1cb3beb56aca9a68edd812e0d F ext/misc/base85.c 073054111988db593ef5fdb87ab8c459df1ea0c3aaaddf0f5bfa3d72b7e6280a F ext/misc/basexx.c 89ad6b76558efbceb627afd5e2ef1d84b2e96d9aaf9b7ecb20e3d00b51be6fcf F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a -F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9 -F ext/misc/carray.c 0ba03f1e6647785d4e05b51be567f5652f06941314ff9d3d3763900aa353b6b5 +F ext/misc/btreeinfo.c cb952620eedf5c0b7625b678f0f08e54d2ec0011d4e50efda5ebdc97f3df7d04 +F ext/misc/carray.c 34fac63770971611c5285de0a9f0ac67d504eaf66be891f637add9290f1c76a5 F ext/misc/carray.h 503209952ccf2431c7fd899ebb92bf46bf7635b38aace42ec8aa1b8d7b6e98a5 F ext/misc/cksumvfs.c 9224e33cc0cb6aa61ff1d7d7b8fd6fe56beca9f9c47954fa4ae0a69bef608f69 -F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243 -F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9 +F ext/misc/closure.c 0e04f52d93e678dd6f950f195f365992edf3c380df246f3d80425cba4c13891e +F ext/misc/completion.c ef78835483b43ac18c96be312b90b615d8368189909be03513ab7a9338131298 F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9 -F ext/misc/csv.c ca8d6dafc5469639de81937cb66ae2e6b358542aba94c4f791910d355a8e7f73 +F ext/misc/csv.c 575c2c05fba0a451586a4d42c2c81e711780c41e797126f198d8d9e0a308dcdb F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01 F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 -F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd970fe -F ext/misc/fileio.c 4e7f7cd30de8df4820c552f14af3c9ca451c5ffe1f2e7bef34d598a12ebfb720 -F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5 -F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d +F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b +F ext/misc/fileio.c d88e60f63557d76d4e38acffda5556b2ab42e98f5d830897f22aba65930d975c +F ext/misc/fossildelta.c 8c026e086e406e2b69947f1856fa3b848fff5379962276430d10085b8756b05a +F ext/misc/fuzzer.c 8b28acf1a7e95d50e332bdd47e792ff27054ad99d3f9bc2e91273814d4b31a5a F ext/misc/ieee754.c 62a90978204d2c956d5036eb89e548e736ca5fac0e965912867ddd7bb833256d -F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d +F ext/misc/memstat.c 5b284b78be431c1f5fa154b18eade2407e42c65ed32ec9e9fbf195d114778d7d F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b F ext/misc/memvfs.c 7dffa8cc89c7f2d73da4bd4ccea1bcbd2bd283e3bb4cea398df7c372a197291b F ext/misc/mmapwarm.c 347caa99915fb254e8949ec131667b7fae99e2a9ce91bd468efb6dc372d9b7a9 @@ -371,32 +379,32 @@ F ext/misc/noop.c 81efe4cad9ec740e64388b14281cb983e6e2c223fed43eb77ab3e34946e0c1 F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405 F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691 -F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196 -F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009 +F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6 +F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c F ext/misc/randomjson.c 7dd13664155319d47b9facc0d8dbf45e13062966a47168e54e3f26d48240d7ea F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab84070963624047db F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c dde5ba69cb9053ff32b5afd64e8d202472325bc052301e31e4d9c0d87e4fff50 +F ext/misc/series.c 80692f675de989629ee20796f75010ce87ca826cb383131040e84f7e1bea5d7a F ext/misc/sha1.c 4011aef176616872b2a0d5bccf0ecfb1f7ce3fe5c3d107f3a8e949d8e1e3f08d F ext/misc/shathree.c 543af7ce71d391cd3a9ab6924a6a1124efc63211fd0f2e240dc4b56077ba88ac F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f +F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea F ext/misc/sqlar.c 53e7d48f68d699a24f1a92e68e71eca8b3a9ff991fe9588c2a05bde103c6e7b7 -F ext/misc/stmt.c bc30d60d55e70d0133f10ac6103fe9336543f673740b73946f98758a2bb16dd7 -F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4 +F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 +F ext/misc/templatevtab.c 10f15b165b95423ddef593bc5dcb915ec4eb5e0f1066d585e5435a368b8bc22b F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b -F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9 +F ext/misc/unionvtab.c 716d385256d5fb4beea31b0efede640807e423e85c9784d21d22f0cce010a785 F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917b9c751 F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 -F ext/misc/vfsstat.c 474d08efc697b8eba300082cb1eb74a5f0f3df31ed257db1cb07e72ab0e53dfb -F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae +F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d +F ext/misc/vtablog.c f2c9d41afe00b51b2c8307b79f508eb0c2dcd57bae074807944e73376fcf15b7 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd -F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546 -F ext/misc/zipfile.c b1f36004c19fb5f949fb166fc4ab88e96a86f66629e9ddb4736a45b63fc3d553 +F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 +F ext/misc/zipfile.c 59af123b4595801d495f55167523b68e840b8e5bfcbbb73f84cbc6a65a994ac2 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255 @@ -445,7 +453,7 @@ F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69 F ext/rbu/sqlite3rbu.c d4ddf8f0e93772556e452a6c2814063cf47efb760a0834391a9d0cd9859fa4b9 F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304 F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055 -F ext/recover/dbdata.c 81661e3a98cabb70be8f2760a67a8d6d5bf7aaa7a4055a53ff915ac884221a64 +F ext/recover/dbdata.c fc7147a68422cbbbaa481ee92ae1752cc25f5a24302bece1c70dcb76345bd736 F ext/recover/recover1.test c484d01502239f11b61f23c1cee9f5dd19fa17617f8974e42e74d64639c524cf F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3 @@ -464,7 +472,7 @@ F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0 F ext/recover/test_recover.c 1a34e2d04533d919a30ae4d5caeb1643f6684e9ccd7597ca27721d8af81f4ade F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 F ext/repair/checkfreelist.c e21f06995ff4efdc1622dcceaea4dcba2caa83ca2f31a1607b98a8509168a996 -F ext/repair/checkindex.c 4383e4469c21e5b9ae321d0d63cec53e981af9d7a6564be6374f0eeb93dfc890 +F ext/repair/checkindex.c af5c66463f51462d8a6f796b2c44ef8cfa1116bbdc35a15da07c67a705388bfd F ext/repair/sqlite3_checker.c.in 445118c5f7fea958b36fba1b2c464283e60ed4842039ddee3265f1698115ebf7 F ext/repair/sqlite3_checker.tcl a9a2caa9660567257c177a91124d8c0dccdfa341e25c51e6da7f1fd9e601eafa F ext/repair/test/README.md 34b2f542cf5be7bffe479242b33ee3492cea30711e447cc4a1a86cb5915f419e @@ -472,10 +480,10 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782 F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c335096108c12c01bddbadcec F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/geopoly.c e969a9afaa603728a553af6b945b5459fbd3b8d112a7eda9e73a6790606c7a41 -F ext/rtree/rtree.c b3b1c96e46fc820b57851b4fbab546c5317d40d1a2d54e23c9bb50be6090b3e0 +F ext/rtree/geopoly.c 0dd4775e896cee6067979d67aff7c998e75c2c9d9cd8d62a1a790c09cde7adca +F ext/rtree/rtree.c da842644466b84391e9fa1b1d5a17f461b475b8e36f1217117d1d98ad5f437e3 F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 -F ext/rtree/rtree1.test 877d40b8b61b1f88cec9d4dc0ff8334f5b05299fac12a35141532e2881860e9d +F ext/rtree/rtree1.test ecc881fdd1bc10fc390faa988ad93343739af84384e4cf3619fed7afada66a30 F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d F ext/rtree/rtree3.test 272594f88c344e973864008bbe4c71fd3a41a264c097d568593ee7886d83d409 F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b @@ -513,7 +521,7 @@ F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8 F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a F ext/session/session1.test e94f764fbfb672147c0ef7026b195988133b371dc8cf9e52423eba6cad69717e F ext/session/session2.test ee83bb973b9ce17ccce4db931cdcdae65eb40bbb22089b2fe6aa4f6be3b9303f -F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479 +F ext/session/session3.test 2cc1629cfb880243aec1a7251145e07b78411d851b39b2aa1390704550db8e6a F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 35279f2ec45448cd2e24a61688219dc6cf7871757716063acf4a8b5455e1e926 @@ -529,13 +537,16 @@ F ext/session/sessionG.test 3efe388282d641b65485b5462e67851002cd91a282dc95b685d0 F ext/session/sessionH.test 71bbff6b1abb2c4ac62b84dee53273c37e0b21e5fde3aed80929403e091ef859 F ext/session/session_common.tcl e5598096425486b363718e2cda48ee85d660c96b4f8ea9d9d7a4c3ef514769da F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3 +F ext/session/sessionalter.test 72722f6f971c7cb6302a1a3c43ff256c0db1aaf19ae625ecdf710d53f08b1237 F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b85419035bc04b45ee F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec F ext/session/sessionfault.test 573bf027fb870d57bd4e7cf50822a3e4b17b2b923407438747aaa918dec57a09 F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576dc79ed344c46fbf41c +F ext/session/sessionfault3.test 7c7547202775de268f3fe6f074c4d0d165151829710b4e64f90d4a01645ba9e7 F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 +F ext/session/sessionnoact.test 506526a5fe29421ecc50d371774ef1bb04cbd9d906a8a468f0556cdbde184c22 F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7 F ext/session/sessionnoop2.test de4672dce88464396ec9f30ed08c6c01643a69c53ae540fadbbf6d30642d64e8 F ext/session/sessionrebase.test 702378bdcb5062f1106e74457beca8797d09c113a81768734a58b197b5b334e2 @@ -543,9 +554,9 @@ F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795 F ext/session/sessionstat1.test b039e38e2ba83767b464baf39b297cc0b1cc6f3292255cb467ea7e12d0d0280c F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc -F ext/session/sqlite3session.c 0fe9107318140cefa1b50f2e1e0f330ab359022599e5976820db349f33efae11 -F ext/session/sqlite3session.h 653e9d49c4edae231df8a4c8d69c2145195aedb32462d4b44229dbee7d2680fb -F ext/session/test_session.c 5285482f83cd92b4c1fe12fcf88210566a18312f4f2aa110f6399dae46aeccbb +F ext/session/sqlite3session.c a0694a23f9c72f25e98b7c3a1bc8cfa7e5903d4edafe31efec47de7cd54f5df9 +F ext/session/sqlite3session.h 4cf19a51975746d7cff2fdd74db8b769c570958e1c3639ac150d824ac1553b3e +F ext/session/test_session.c 73e9921205633a08c1497770beecf3dcbc9b826dd4358f7f8152f706eaac5d71 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb @@ -568,18 +579,18 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219 F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e -F ext/wasm/api/sqlite3-api-glue.js b65e546568f1dfb35205b9792feb5146a6323d71b55cda58e2ed30def6dd52f3 +F ext/wasm/api/sqlite3-api-glue.js 26aedfb27915f4f316f6eac84078443e4f0d2dfe5f012310014923ed4b77b2b6 F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8 F ext/wasm/api/sqlite3-api-prologue.js 9aeba7b45cf41b3a26d34d7fb2525633cd1adfc544888c1ea8dbb077496f4ce9 -F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec +F ext/wasm/api/sqlite3-api-worker1.js f941382f21006b4a817754184e2661b0a63ce650201f3419cd60f4758b6fd60e F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379 F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25 -F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 327a8c363a8c84c61770dc3c46cc83d7cc0eb6b59a3b29728bddf087651d3b77 +F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 595953994aa3ae2287c889c4da39ab3d6f17b6461ecf4bec334b7a3faafddb02 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 46c4afa6c50d7369252c104f274ad977a97e91ccfafc38b400fe36e90bdda88e -F ext/wasm/api/sqlite3-wasm.c 65d60439671e24d50d9119ca805ac1c68fb36129e164377eb46f8d037bd88b07 +F ext/wasm/api/sqlite3-wasm.c c8c5b81b838cef2053b1eb6e7a79c44a2caedcf0c9e6b0d12a45d73ce0617be0 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f -F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75 +F ext/wasm/api/sqlite3-worker1.c-pp.js a541112aa51e16705f13a99bb943c64efe178aa28c86704a955f8fd9afe4ba37 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 F ext/wasm/batch-runner.js 0dad6a02ad796f1003d3b7048947d275c4d6277f63767b8e685c27df8fdac93e F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25b4 @@ -622,7 +633,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 9e0f4da49f02753a73a5f931bfb9b1458175518daa3fec40b5ebdc06c285539c +F ext/wasm/tester1.c-pp.js fb20d9e1c308ea34a29d8afdda1a6c5edc406241b5560fa23c19c14747ee41bc F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -642,39 +653,39 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 -F src/alter.c 3ff8c2fca0c0636d43459154bb40d79c882df1b34df77f89c4ec47ab2e2389f5 +F src/alter.c 30c2333b8bb3af71e4eb9adeadee8aa20edb15917ed44b8422e5cd15f3dfcddc F src/analyze.c d4cc28738c29e009640ec20ebb6936ba6fcefff0d11aa93398d9bb9a5ead6c1f F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39 F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4 F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645 F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 -F src/btree.c d2e73513d382e6e4829b823fb41b5f2eddd9c5984b1492a7a6333cd91be15601 +F src/btree.c 58f5cca2aced6888824ed69d19a0c398d288d0840b1c72c0834525e82b10c076 F src/btree.h 03e3356f5208bcab8eed4e094240fdac4a7f9f5ddf5e91045ce589f67d47c240 -F src/btreeInt.h 91a9e0c41a0e71fa91a742ec285c63dd8dcb38b73d14fae0ed7209174ff0fdc1 -F src/build.c 79a4edcee69df5f20963d7b11faf0820d25e6f8c11ef3a9f868d14be87834711 +F src/btreeInt.h ef12a72b708677e48d6bc8dcd66fed25434740568b89e2cfa368093cfc5b9d15 +F src/build.c 1a9061ab67987cfa9c7f9d52ccc862a31d37ad2b05faaf0d72eeb4b4b5ee37cf F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c db847fac81837ff5e5028a5f7505147ac645ae676104adc5bc08e356f243de40 +F src/ctime.c 23331529e654be40ca97d171cbbffe9b3d4c71cc53b78fe5501230675952da8b F src/date.c eebc54a00e888d3c56147779e9f361b77d62fd69ff2008c5373946aa1ba1d574 -F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 -F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef +F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782 +F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43 F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500 -F src/expr.c 9902bebcc9fa2b2c4cc94b7aa5615afe1affc98a986553aa7b239971c54ddea8 +F src/expr.c 0a499c92bef5129e516c229fb305a6345be24ccb5ae6d63eaff91705ec06fa7e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c a7fcbf7e66d14dbb73cf49f31489ebf66d0e6006c62b95246924a3bae9f37b36 -F src/func.c 154f08966f8a3a7cad6c438205df1abf58fb2826961a0683e82e120fa647e84c +F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00 +F src/func.c 472f6dcfa39cf54f89a6aec76c79c225fb880a6c14469c15d361331662b9bf43 F src/global.c 29f56a330ed9d1b5cd9b79ac0ca36f97ac3afc730ff8bfa987b0db9e559d684d F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276 -F src/json.c 51141f1c09ccb177057e5813e6302a5e32e5ba88cc4a756318a35081010fc6df +F src/json.c d69c6e28ff7b602877bda68cd20583b8487c059759aa4d154dd21b3fd99c6238 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa -F src/loadext.c 98cfba10989b3da6f1807ad42444017742db7f100a54f1032af7a8b1295912c0 -F src/main.c 618aeb399e993cf561864f4b0cf6a331ee4f355cf663635f8d9da3193a46aa40 -F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23 +F src/loadext.c 7d56c6f28aaf9b42e2772289e0d0a12a77b57c2baed021dbfd1fcafec69c156a +F src/main.c db12d1e572b6bbb617bcc6686f18aba30b49a6c257bacbabcb81320653029b23 +F src/malloc.c f016922435dc7d1f1f5083a03338a3e91f8c67ce2c5bdcfa4cdef62e612f5fcc F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 @@ -683,12 +694,12 @@ F src/mem5.c b7da5c10a726aacacc9ad7cdcb0667deec643e117591cc69cf9b4b9e7f3e96ff F src/memdb.c 559c42e61eb70cd6d4bc692b042497133c6d96c09a3d514d92f3dac72268e223 F src/memjournal.c c283c6c95d940eb9dc70f1863eef3ee40382dbd35e5a1108026e7817c206e8a0 F src/msvc.h 80b35f95d93bf996ccb3e498535255f2ef1118c78764719a7cd15ab4106ccac9 -F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25 +F src/mutex.c 1b4c7e5e3621b510e0c18397210be27cd54c8084141144fbbafd003fde948e88 F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 -F src/mutex_unix.c bd52ec50e44a41fe1e3deb5a6e3fe98edb6f2059da3e46d196363d0fa3192cda +F src/mutex_unix.c f7ee5a2061a4c11815a2bf4fc0e2bfa6fb8d9dc89390eb613ca0cec32fc9a3d1 F src/mutex_w32.c 38b56d0bc8d54c17c20cbaaad3719b0c36b92fd07a7e34360d0c6a18d5589912 -F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6 +F src/notify.c 57c2d1a2805d6dee32acd5d250d928ab94e02d76369ae057dee7d445fd64e878 F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 @@ -697,52 +708,52 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210 F src/os_unix.c 2e8b12107f75d1bd16412f312b4c5d5103191807a37836d3b81beb26436ad81b F src/os_win.c 4a50a154aeebc66a1f8fb79c1ff6dd5fe3d005556533361e0d460d41cb6a45a8 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 993445a19b611d473ca007542ab3149840661a4c7e9f2d9e1ec008b7cc2abe78 +F src/pager.c 2188897e1102a776dcb1bbe8b2eb70ac7de8863c9cb95ef09d35e9bad406cf45 F src/pager.h f4d33fec8052603758792045493423b8871a996da2d0973927b7d36cd6070473 -F src/parse.y aeb7760d41cfa86465e3adba506500c021597049fd55f82a30e5b7045862c28c +F src/parse.y 020d80386eb216ec9520549106353c517d2bbc89be28752ffdca649a9eaf56ec F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00 -F src/pragma.c ea85fb64b9481004aaa5d0fa66a57c804074f46145ef2409894d1fc2f4b0cf8d +F src/pragma.c 10dae0459c38201427c4550607f58ec0c865092f26e7966fd637e7e2b5156c82 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 -F src/prepare.c 80548297dc0e1fb3139cdebffb5a1bcac3dfac66d791012dd74838e70445072d -F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2 +F src/prepare.c bde74add20fc0e8ce0c4e937a1f70a36d17413afe4f71d3e103f5cb74b17c8d9 +F src/printf.c 9da63b9ae1c14789bcae12840f5d800fd9302500cd2d62733fac77f0041b4750 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 0c3046b88901336709cd09f474303a16fc54bce13a2befcab66d0fa6b44ca869 +F src/resolve.c 31229276a8eb5b5de1428cd2d80f6f1cf8ffc5248be25e47cf575df12f1b8f23 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 7f9155185be78902818b21c2cd3e33f01b4306279a15d6719eb1bbb9779034aa -F src/shell.c.in 62708bea44d4e43aa7b1270ed422d1d29e82297924d4e0f223c39336a3f582f8 -F src/sqlite.h.in 931a58d119d5cf87110648f39fa0bb9f1738b0068cb68250d893304a471bd6c0 +F src/select.c f9d8ece7f0742d7b835efa9590ccda4eccee5b9def7581ec94f556e3c52efe51 +F src/shell.c.in 66995332610ed7d47483152c4c78810519ca9ac8b2f93ee884127ce330ca12e8 +F src/sqlite.h.in b37b3df6fb0684929446c095e81287fbdffd64f55481e4195ee7768f2f0ae72e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 2f30b2671f4c03cd27a43f039e11251391066c97d11385f5f963bb40b03038ac -F src/sqliteInt.h f2d713fac835f32b131d8a334595b0c471ede3796dab527c705d2b03c32d14e9 +F src/sqliteInt.h cf6646e8694a63749096e1f086767a2c1920dca9848ec2dbe9f7bfb961d322ef F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c ecbc3c99c0d0c3ed122a913f143026c26d38d57f33e06bb71185dd5c1efe37cd -F src/test1.c 57bd144d022ed1356ae5238110beb251e79b0db5cc1ec44ef5b2f44306adb75f +F src/test1.c f9620e8f0d0fa4edb239201a732c4dd1562f0cdd9741955c89332d49e14a5edd F src/test2.c 54520d0565ef2b9bf0f8f1dcac43dc4d06baf4ffe13d10905f8d8c3ad3e4b9ab F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664 F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d F src/test6.c e53bc69dc3cb3815fb74df74f38159ec05ba6dd5273216062e26bc797f925530 -F src/test8.c ccc5d3e2a2bf7248f7da185e2afc4c08b4c6840447f5eb4dd106db165fddbdbc +F src/test8.c 303c2e3bcf7795e888810a7ef03809602b851f0ebec8d6e06a429ed85cafd9a2 F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871 F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 -F src/test_bestindex.c 68c62586d2ae9f032903fe53be743657d0c2aac0a850b880938b668e1161d516 +F src/test_bestindex.c f6af1e41cb7901edafb065a8198e4a0192dd42432b642d038965be5e628dec12 F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c f0cc1f517deaa96dd384822ae2bb91534fa56aa458528b439830d709941d3932 F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c 38a459d1c78fd9afa770445b224c485e079018d6ac07332ff9bd07b54d2b8ce9 F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86 -F src/test_fs.c ba1e1dc18fd3159fdba0b9c4256f14032159785320dfbd6776eb9973cb75d480 +F src/test_fs.c 56cc17e4fdc57efa61695026e2ba96e910b17060d7ee01d775ec048791522e2f F src/test_func.c 24df3a346c012b1fc9e1001d346db6054deb426db0a7437e92490630e71c9b0a F src/test_hexio.c 9478e56a0f08e07841a014a93b20e4ba2709ab56d039d1ca8020e26846aa19bd F src/test_init.c f2cc4774b7c9140f76e45ecbb2ae219f68e3acbbe248c0179db666a70eae9f08 -F src/test_intarray.c 39b4181662a0f33a427748d87218e7578d913e683dc27eab7098bb41617cac71 +F src/test_intarray.c 26ffba666beb658d73cd925d9b4fb56913a3ca9aaeac122b3691436abb192b92 F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293 F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f4e287 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd @@ -752,17 +763,17 @@ F src/test_multiplex.c 70479161239d65af2a231550b270e9d11ece717ad7bf0e13ef4220658 F src/test_multiplex.h f0ff5b6f4462bfd46dac165d6375b9530d08089b7bcbe75e88e0926110db5363 F src/test_mutex.c cd5bac43f2fd168f43c4326b1febe0966439217fac52afb270a6b8215f94cb40 F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4 -F src/test_osinst.c d341f9d7613e007c8c3f7eba6cd307230047506aa8f97858c1fd21f5069616bd +F src/test_osinst.c 8e11faf10f5d4df10d3450ecee0b8f4cfa2b62e0f341fafbeb480a08cefeaec4 F src/test_pcache.c 3960cd2c1350adc992c4bf7adcfb0d1ac0574733012bd1a5f94e195928577599 F src/test_quota.c ea44c05f29b995bdb71c55eb0c602604884e55681d59b7736e604bbcc68b0464 F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d F src/test_rtree.c 671f3fae50ff116ef2e32a3bf1fe21b5615b4b7b -F src/test_schema.c f5d6067dfc2f2845c4dd56df63e66ee826fb23877855c785f75cc2ca83fd0c1b +F src/test_schema.c cbfd7a9a9b6b40d4377d0c76a6c5b2a58387385977f26edab4e77eb5f90a14ce F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 9fdb13b1df05e639808d44fcb8f6064aaded32b6565c00b215cfd05a060d1aca F src/test_tclsh.c 3ff5d188a72f00807425954ea3b493dfd3a4b890ecc6700ea83bad2fd1332ecf -F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc +F src/test_tclvar.c 3273f9d59395b336e381b53cfc68ec6ebdaada4e93106a2e976ffb0550504e1c F src/test_thread.c 7ddcf0c8b79fa3c1d172f82f322302c963d923cdb503c6171f3c8081586d0b01 F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43 F src/test_vfs.c 193c18da3dbf62a0e33ae7a240bbef938a50846672ee947664512b77d853fe81 @@ -773,48 +784,49 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 23d9f4539880b40226254ad9072f4ecf12eb1902e62aea47aac29928afafcfd5 -F src/treeview.c 1d52fbc4e97161e65858d36e3424ea6e3fc045dd8a679c82b4b9593dc30de3bd -F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0 +F src/treeview.c 62fafcd31eea60b718f8daf448116b7b19f90134ebc6c20777ddbb07f56a3d28 +F src/trigger.c 5286019b152f622a38900284109e4aae1e5f566deb7ad9ba7e931f0660771f32 F src/update.c 6904814dd62a7a93bbb86d9f1419c7f134a9119582645854ab02b36b676d9f92 F src/upsert.c fa125a8d3410ce9a97b02cb50f7ae68a2476c405c76aa692d3acf6b8586e9242 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 -F src/util.c e87f66258c37f87724f46e849572c3ece4c74ef5614ba41eb221e98f0dbc95de +F src/util.c b22cc9f203a8c0b9ee5338a67f8860347d14845864c10248bebe84518a781677 F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104 -F src/vdbe.c cd112eb00d20fc5cc44f631d0e713838602637328b0f127c2f3c2aa8cea3cc91 +F src/vdbe.c 300b1ac9339a5b7db9ccd48c1a13c3d71722da13352a38ee042ca0a399b4dd7e F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0 F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c -F src/vdbeapi.c 4184402246172220418c0ef49ff4cf1a19ced9a4ac6c843c2f0773fb5c543f37 -F src/vdbeaux.c 5b415e09b5b9d5be6c0f4fcbf18ea9d7d16f6a29ced2f14a3b2041020f63e9c1 -F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce -F src/vdbemem.c 317b9f48708139db6239ade40c7980b4bc8233168383690d588dad6d8437f722 -F src/vdbesort.c 0d40dca073c94e158ead752ef4225f4fee22dee84145e8c00ca2309afb489015 +F src/vdbeapi.c fe654b1f54e1feebcaed6c2ae3ed035cc65bfeb9a1169bed866abc42bfc63ff6 +F src/vdbeaux.c 929a4edecf9845fb063b47b23b9d187473a648470d915521cf72419f5219c4b7 +F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5 +F src/vdbemem.c c936e9002af4993b84c4eb7133d6b1190efe46d391cc86117ecd67ba17b1a04b +F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 -F src/vdbevtab.c 57fa8f56478e5b5cb558cb425e7878515e0a105c54f96f1d1bbf4b9433529254 +F src/vdbevtab.c 2143db7db0ceed69b21422581f434baffc507a08d831565193a7a02882a1b6a7 F src/vtab.c 154725ebecd3bc02f7fbd7ad3974334f73fff76e02a964e828e48a7c5fb7efff F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 01e051a1e713d9eabdb25df38602837cec8f4c2cae448ce2cf6accc87af903e9 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 -F src/where.c b05f3e60d576a0415948ca1e86754a3c564c0d9e89e3011e35f849cc4d818ef8 +F src/where.c 313ce81270d2a414672370e1ee74e65949ad620519193d4cac2986d073cbc8a0 F src/whereInt.h 4b38c5889514e3aead3f27d0ee9a26e47c3f150efc59e2a8b4e3bc8835e4d7a1 F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1 F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00 -F src/window.c b7ad9cff3ce8ae6f8cc25e18e1a258426cb6bd2999aace6f5248d781b2a74098 +F src/window.c ad21e2b73ec75acc79dde2576c573f54a338b0c49e9de847ce984f9b9595b5e2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggfault.test 777f269d0da5b0c2524c7ff6d99ae9a93db4f1b1839a914dd2a12e3035c29829 -F test/aggnested.test 7269d07ac879fce161cb26c8fabe65cba5715742fac8a1fccac570dcdaf28f00 +F test/aggnested.test 2e738bfe2980df301a782f6e7bbf9459266f64f7e72f58f3b5c843bf897c568c +F test/aggorderby.test d110490c62d29318fa56831cd67bc49b07789592f1cdd7881725735ecd05308a F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 -F test/alter.test 313073774ab5c3f2ef1d3f0d03757c9d3a81284ae7e1b4a6ca34db088f886896 +F test/alter.test 403a7f8842457044a994d0ffb42963d6e84fcfbf5e8f54556063b25d966cd454 F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687 F test/alter3.test ffc4ab29ce78a3517a66afd69b2730667e3471622509c283b2bd4c46f680fba3 F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 48967abae0494d9a300d1c92473d99fcb66edfcc23579c89322f033f49410adc -F test/altercol.test 8465ca659c2c55a359cf16cc261df4fcb5c45a5f104a50827c337ae66c09dc15 +F test/altercol.test 29fed774747777fbbaacdd865b4413ed2d0844a4c824f8af531b5c7d4a832087 F test/altercorrupt.test 2e1d705342cf9d7de884518ddbb053fd52d7e60d2b8869b7b63b2fda68435c12 F test/alterdropcol.test a653a3945f964d26845ec0cd0a8e74189f46de3119a984c5bc45457da392612e F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41 @@ -823,11 +835,11 @@ F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e2 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test 17fb3724c4b004c469c27dc4ef181608aa644555fbd3f3236767584f73747c81 F test/altermalloc3.test 8531b3086f0a7889f43971a579a8c81832d5123f4703d8c86b89ba1136c63b9a -F test/alterqf.test ff6c6f881485c29ed699b8ef4774864ca1b0c01a6c08f5cdd624a008e4b40fca +F test/alterqf.test 8ec03d776de9c391daa0078ea8f838903bdcfb11dfae4ba3576b48436834ccba F test/altertab.test 8a2712f9076da5012a002d0b5cc0a421398a5bf61c25bab41b77c427586a7a27 F test/altertab2.test 62597b6fd08feaba1b6bfe7d31dac6117c67e06dc9ce9c478a3abe75b5926de0 F test/altertab3.test 6c432fbb9963e0bd6549bf1422f6861d744ee5a80cb3298564e81e556481df16 -F test/altertrig.test fb5951d21a2c954be3b8a8cf8e10b5c0fa20687c53fd67d63cea88d08dd058d5 +F test/altertrig.test aacc980b657354fe2d3d4d3a004f07d04ccc1a93e5ef82d68a79088c274ddc6b F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b F test/analyze3.test 03f4b3d794760cf15da2d85a52df9bae300e51c8fefe9c36cfae1f86dc10d23f @@ -891,8 +903,8 @@ F test/bestindex5.test a0c90b2dad7836e80a01379e200e5f8ec9476d49b349af02c0dbff2fb F test/bestindex6.test 16942535b551273f3ad9df8d7cc4b7f22b1fcd8882714358859eb049a6f99dd4 F test/bestindex7.test f094c669a6400777f4d2ddc3ed28e39169f1adb5be3d59b55f22ccf8c414b71e F test/bestindex8.test 333ad8c6a554b885a49b68c019166eda92b05f493a92b36b0acdf7f766d04dad -F test/bestindex9.test bf2eb8556e8d5c00ef3ee18c521751cd03c1b55454b6e7683b4c6742e3131b23 -F test/bestindexA.test dd7b7439a46169b45d0305c4cbbb14fc20c7044acc2055c767d2f838b3479c3f +F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede39673a451a0 +F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -930,8 +942,8 @@ F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/carray01.test 23ed7074307c4a829ba5ff2970993a9d87db7c5cdbbe1a2cbef672d0df6d6e31 F test/cast.test af2286fdd28f3470b7dcad23977282b8cc117747ad55acff74a770dad3b19398 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/changes.test 9dd8e597d84072122fc8a4fcdea837f4a54a461e6e536053ea984303e8ca937b -F test/changes2.test d222c0cbf5ab0ac4d7c180594e486c1bf20b2098d33e56ce33b8e12eba6823b9 +F test/changes.test 4377d202a487f66fc2822c1bf57c46798c8b2caf7446f4f701723b1dbb6b86f6 +F test/changes2.test 07949edcc732af28cb54276bfb7d99723bccc1e905a423648bf57ac5cb0dc792 F test/check.test 56e4ed457e9f8683b9fc56f5b964f461f6e8a8dd5a13f3d495408215d66419ed F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760 @@ -1006,11 +1018,11 @@ F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64a F test/date4.test db9e5760cf6f480fcf36bb7ca8e215880ff44354a31be6fb3d7e58f9d2e057e9 F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e -F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30 +F test/dbfuzz001.test 6c9a4622029d69dc38926f115864b055cb2f39badd25ec22cbfb130c8ba8e9c3 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23 F test/dbpage.test fce29035c7566fd7835ec0f19422cb4b9c6944ce0e1b936ff8452443f92e887d -F test/dbpagefault.test d9111a62f3601d3efc6841ace3940181937342d245f92a1cca6cba8206d4f58a +F test/dbpagefault.test 35f06cfb2ef100a9b19d25754e8141b9cba9b7daabd4c60fa5af93fcce884435 F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef F test/decimal.test ef731887b43ee32ef86e1c8fddb61a40789f988332c029c601dcf2c319277e9e @@ -1026,7 +1038,7 @@ F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a199 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test 691c9e850b0d0b56b66e7e235453198cb4cf0760e324b7403d3c5abbeab0a014 F test/distinct2.test bb71cc7b5e58e895787f9910a788c254f679928d324732d063fe9bc202ecbe71 -F test/distinctagg.test 14ec5026e684eddd414c61c08692b43773e224ac92efbed6ec08c6994bc39723 +F test/distinctagg.test ad2b4cf1483cd4cf24867dfafbfa0abb61184d92085fcc9784cea0592b278d64 F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52 F test/e_blobclose.test 692fc02a058476c2222a63d97e3f3b2b809c1842e5525ded7f854d540ac2e075 F test/e_blobopen.test 29f6055ee453b8e679fe9570c4d3acfedbef821622c5dad16875148c5952ef50 @@ -1036,13 +1048,13 @@ F test/e_createtable.test 31b9bcb6ac8876bc7ec342d86d9c231a84c62b442093a6651dfd0f F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7 -F test/e_expr.test 27e905ed17266c745bffe65f56b809c13ae6e225e56aeda1aaec926b32439286 +F test/e_expr.test b950818a48269506d75a41c819003bd77a0893bc4a4f2fdee191bc74109c1a87 F test/e_fkey.test feeba6238aeff9d809fb6236b351da8df4ae9bda89e088e54526b31a0cbfeec5 F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e F test/e_reindex.test 2b0e29344497d9a8a999453a003cb476b6b1d2eef2d6c120f83c2d3a429f3164 F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8 -F test/e_select.test 89fa483f68d868f1be3d6f56180ed42d979979c266e051bf8b5e66a251e6b44a +F test/e_select.test 327a15f14068bbd6f647cedc67210f8680fcb2f05e481a0a855fccd2abfa1292 F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test c927f7499dc3aa28b9b556b7d6d115a2f0fe41f012b128d16bf1f3b30e9b41e4 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 @@ -1075,7 +1087,7 @@ F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3 F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4 F test/filter1.test 590f8ba9a0cd0823b80d89ac75c5ce72276189cef9225d2436adaf1ee87f3727 F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f93393e8 -F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a +F test/filter2.test 3cc20eaea2ea1ab245197cc4a62468deb460b78f5aa9bd7d5d3353c2fe569bae F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b F test/fkey1.test e563bcb4cb108ce3f40363cda4f84009dc89a39e2973076e5057ba99fca35378 F test/fkey2.test 1063d65e5923c054cfb8f0555a92a3ae0fa8c067275a33ee1715bd856cdb304c @@ -1119,7 +1131,7 @@ F test/fts3conf.test c9cd45433b6787d48a43e84949aa2eb8b3b3d242bac7276731c1476290d F test/fts3corrupt.test 6732477c5ace050c5758a40a8b5706c8c0cccd416b9c558e0e15224805a40e57 F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test 64c6729721575e16bb7fdfc3d23092bb84ac032b0980b891a10483cb84bc1931 +F test/fts3corrupt4.test 48bd57baed9654e511709a02dbef2d22ee54c012ad466e8648f0f825233faa08 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525 F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf @@ -1139,7 +1151,7 @@ F test/fts3f.test 8c438d5e1cab526b0021988fb1dc70cf3597b006a33ffd6c955ee89929077f F test/fts3fault.test f4e1342acfe6d216a001490e8cd52afac1f9ffe4a11bbcdcb296129a45c5df45 F test/fts3fault2.test 7b2741e5095367238380b0fcdb837f36c24484c7a5f353659b387df63cf039ec F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 -F test/fts3fuzz001.test e3c7b0ce9b04cc02281dcc96812a277f02df03cd7dc082055d87e11eb18aaf56 +F test/fts3fuzz001.test c78afcd8ad712ea0b8d2ed50851a8aab3bc9dc52c64a536291e07112f519357c F test/fts3join.test 1a4d786539b2b79a41c28ef2ac22cacd92a8ee830249b68a7dee4a020848e3bb F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test aa66cc50615578b30f6df9984819ae5b702511cf8a94251ec7c594096a703a4a @@ -1168,7 +1180,7 @@ F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269 F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d F test/fts4langid.test 4be912f42454998e239a2e877600263e0394afbaba03e06cedcc5a08693a345a F test/fts4lastrowid.test 185835895948d5325c7710649824042373b2203149abe8024a9319d25234dfd7 -F test/fts4merge.test e2b2ec21e287d54ec09824ccfb41e66896eeca568fc818ba0e0eb2efd94c35d2 +F test/fts4merge.test 57d093660a5093ae6e9fbd2d17592a88b45bbd66db2703c4b640b28828dbe38b F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0 F test/fts4merge4.test 66fce89934cd9508cbdc67de486558c34912ffb2e8ffe5c9a1bbb9b8a4408ba7 @@ -1183,7 +1195,7 @@ F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f75 F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9 F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test cbcf086273529d4a99b7199086da637a99039d2cad81dd7d7c4c9e25258ae164 +F test/func.test 3a29323b640c0552f6e9f1577407ced3a68e7d8c0bc04b61dd6040fa593a3a02 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31 @@ -1207,13 +1219,13 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db b8725a5f5cf7a3b7241a9038e57ca7e7cc8c3f4d86b44bd770617bda245ab2b0 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db 40c85daae47da64387c3dab7bbd99c21e425c0bfdb4b149cb685b1ab474a2cb4 +F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767a35a F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc F test/fuzzinvariants.c b34530e8431f2cf3591eff588fc7684d6fdef466916fb46141c8c5374a3d8099 -F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c -F test/gencol1.test aef8b0670abd4b1ae4cae786b15a43758d86f6cd9f12b381d45d96bb51e597c9 +F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d +F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 @@ -1249,6 +1261,7 @@ F test/index6.test b376a648e85aa71c50074382784e6cb0c126ec46e43d1ad15af9a4d234c52 F test/index7.test b238344318e0b4e42126717f6554f0e7dfd0b39cecad4b736039b43e1e3b6eb3 F test/index8.test caa097735c91dbc23d8a402f5e63a2a03c83840ba3928733ed7f9a03f8a912a3 F test/index9.test 2ac891806a4136ef3e91280477e23114e67575207dc331e6797fa0ed9379f997 +F test/indexA.test 11d84f6995e6e5b9d8315953fb1b6d29772ee7c7803ee9112715e7e4dd3e4974 F test/indexedby.test f21eca4f7a6ffe14c8500a7ad6cd53166666c99e5ccd311842a28bc94a195fe0 F test/indexexpr1.test 62558b1cfd7ccbe7bc015849cc6d1a13ef124e80cbd5b3a98dc66c3c9cce0cf4 F test/indexexpr2.test 1c382e81ef996d8ae8b834a74f2a9013dddf59214c32201d7c8a656d739f999a @@ -1290,7 +1303,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2 F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28 F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127 -F test/joinH.test 5f6107246b8509f9df4745fbdc2107a16f07594770a5c473a25f6c7f672edd86 +F test/joinH.test 84198ea42bf78b79fe399c0567218cd6df36c50c6dd27d9c4aab221acaad929e F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1301,7 +1314,7 @@ F test/json/README.md 63e3e589e1df8fd3cc1588ba1faaff659214003f8b77a15af5c6452b35 F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb91c807307 F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x -F test/json101.test dc9d5a2a5b1fd1b54dbd71c538b17933cc98d84b4c1f821ead754933663dca55 +F test/json101.test bc05d2476fd6f7ead31ec05b43d1b24b2b193ae112fd8f0d2ed56d9a904f9fa5 F test/json102.test 4c69694773a470f1fda34e5f4ba24920b35184fb66050b450fc2ef9ab5ad310b F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1 @@ -1359,9 +1372,9 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 F test/memdb1.test 2c4e9cc10d21c6bf4e217d72b7f6b8ba9b2605971bb2c5e6df76018e189f98f5 -F test/memdb2.test 7789975b96b0726032a22c1afc026592c7ff175bf05be11f1d640791541a77ea +F test/memdb2.test 4ba1fc09e2f51df80d148a540e4a3fa66d0462e91167b27497084de4d1f6b5b4 F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c -F test/memjournal2.test 6b9083cfaab9a3281ec545c3da2487999e8025fb7501bbae10f713f80c56454c +F test/memjournal2.test dbc2c5cb5f7b38950f4f6dc3e73fcecf0fcbed3fc32c7ce913bba164d288da1e F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memsubsys1.test 86b8158752af9188ed5b32a30674a1ef71183e6bc4e6808e815cd658ca9058a6 F test/memsubsys2.test 774b93cb09ca50d1b759bb7c645baa2a9ce172edc3a3da67d5150a26a9fc2a08 @@ -1437,7 +1450,7 @@ F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305 F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035ce4b3 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 -F test/pendingrace.test cbdf0f74bc939fb43cebad64dda7a0b5a3941a10b7e9cc2b596ff3e423a18156 +F test/pendingrace.test 6aa33756b950c4529f79c4f3817a9a1e4025bd0d9961571a05c0279bd183d9c6 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test f7caf8dd5c7b1da74842a48df116f7f193399c656d4ffc805cd0d9658568c675 F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f @@ -1455,7 +1468,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/pushdown.test 1495a09837a1cedfc0adf07ba42dc6b83be05a2c15de331b67c39a0e22078238 F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 -F test/quickcheck.test f86b25b33455af0189b4d3fe7bd6e553115e80b2d7ec9bbe9a6b37fce0881bfe +F test/quickcheck.test a4b7e878cd97e46108291c409b0bf8214f29e18fddd68a42bc5c1375ad1fb80a F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8 @@ -1488,8 +1501,8 @@ F test/rowvalue5.test 00740304ea6a53a8704640c7405690f0045d5d2a6b4b04dde7bccc14c3 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf6f2dba F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 -F test/rowvalue9.test 138252b53b835208a5712e01595403a0ae32b4bc58284d9fe6bea10e58203fe4 -F test/rowvalueA.test 51f79b6098c193f838168752c9640f4eae6c63346bf64b5bed4f4e22fe2c71d0 +F test/rowvalue9.test 7499a8fd7ca3a3f0e19d94e135355439aa2b596f86b775ca8de79672da2ca378 +F test/rowvalueA.test be8d6ad8b476eb24c151bb20bfd487e0d50c5e99618b7b0e656035069d2fc2cf F test/rowvaluefault.test 963ae9cdaed30a85a29668dd514e639f3556cae903ee9f172ea972d511c54fff F test/rowvaluevtab.test cd9747bb3f308086944c07968f547ad6b05022e698d80b9ffbdfe09ce0b8da6f F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 @@ -1502,7 +1515,7 @@ F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test b249328caf4d317e71058006872b8012598a5fa045b30bf24a81eeff650ab49e -F test/scanstatus2.test d0434bc3b356fb9d948f3417846b2ed5bbc4bd4cc49bddb38ac86469f754bfb0 +F test/scanstatus2.test 317670daf7f3eef48a9598cb7800ba8eccab51949cf52bca3f7da3b83a0c1c8c F test/schema.test 5dd11c96ba64744de955315d2e4f8992e447533690153b93377dffb2a5ef5431 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 8ed4ae66e082cdd8b1b1f22d8549e1e7a0db4527a8e6ee8b6193053ee1e5c9ce @@ -1515,7 +1528,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/seekscan1.test 31af16e3bb3203d153aea320939c5da97ec44705c2710d153c06a01397d45b09 F test/select1.test 692e84cfa29c405854c69e8a4027183d64c22952866a123fabbce741a379e889 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 -F test/select3.test 8d04b66df7475275a65f7e4a786d6a724c30bd9929f8ae5bd59c8d3d6e75e6cd +F test/select3.test 180223af31e1ca5537dd395ef9708ae18e651a233777fd366fd0d75469fc19c6 F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f @@ -1532,7 +1545,7 @@ F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae F test/selectH.test 0b54599f1917d99568c9b929df22ec6261ed7b6d2f02a46b5945ef81b7871aac F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb -F test/sessionfuzz.c 5eef09af01eeff6f20250ae4c0112c2e576e4d2f2026cc9a49dc5be6886fa6ee +F test/sessionfuzz.c 666b47e177c7b25f01ba645d41fb9131d2d54ae673f0d81c08f5af2b3e6ecbda F test/shared.test f022874d9d299fe913529dc10f52ad5a386e4e7ff709270b9b1111b3a0f3420a F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test f8cd07c1a2b7cdb315c01671a0b2f8e3830b11ef31da6baa9a9cd8da88965403 @@ -1596,7 +1609,7 @@ F test/sqllimits1.test b28e5cc8d337aaf290614d96a47e8fbfb720bb7ad35620c9d5432996f F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805 F test/stat.test 123212a20ceb496893d5254a5f6c76442ce549fdc08d1702d8288a2bbaac8408 -F test/statfault.test 55f86055f9cd7b2d962a621b8a04215c1cebd4eaaecde92d279442327fe648a0 +F test/statfault.test 064f43379e4992b5221b7d9ac887c313b3191f85cce605d78e416fc4045da64e F test/stmt.test 54ed2cc0764bf3e48a058331813c3dbd19fc1d0827c3d8369914a5d8f564ec75 F test/stmtvtab1.test 6873dfb24f8e79cbb5b799b95c2e4349060eb7a3b811982749a84b359468e2d5 F test/strict1.test 4d2b492152b984fd7e8196d23eb88e2ccb0ef9e46ca2f96c2ce7147ceef9d168 @@ -1619,7 +1632,7 @@ F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef20 F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test 54f27eacd054aa528a8b6e3331192c484104f30aaee351ad035f2b39a00f87c4 -F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 +F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test ad0bbd92edabe64cc91d990a0748142fe5ab962d74ac71fa3bfa94d50d2f4c87 @@ -1631,7 +1644,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 68454ef88508c196d19e8694daa27bff7107a91857799eaa12f417188ae53ede -F test/testrunner.tcl c88eae7d8ba9825d09f080ee2aa98b8e65c381bb56b4d427fb492625d2d4c36b +F test/testrunner.tcl 14c8b8ece841b1dd17516a0dc9c7ad9b5f4d4db7987974d3fdf66ae56b2a71fa F test/testrunner_data.tcl 7f73f93634d32dafc857ed491b840f371113d09fde6a8bfb9e47b938d47b8c85 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -1640,7 +1653,7 @@ F test/thread004.test f51dfc3936184aaf73ee85f315224baad272a87f F test/thread005.test 50d10b5684399676174bd96c94ad4250b1a2c8b6 F test/thread1.test df115faa10a4ba1d456e9d4d9ec165016903eae4 F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46 -F test/thread3.test 5f53b6a8e7391d8653116fd0bee4f9774efee4410e039990821de39c6b4375a9 +F test/thread3.test a12656a56cdf67acb6a2ff7638826c6d6a645f79909d86df521045ad31cf547d F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 @@ -1698,7 +1711,7 @@ F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447 F test/tkt-c694113d5.test 82c461924ada5c14866c47e85535b0b0923ba16a2e907e370061a5ca77f65d77 -F test/tkt-cbd054fa6b.test 708475ef4d730a6853512c8ce363bcbd3becf0e26826e1f4cd46e2f52ff38edf +F test/tkt-cbd054fa6b.test 6ec9f1a5721fba74a83397683c50f472df68a0a749d193a537264eda3ad6d113 F test/tkt-d11f09d36e.test d999b548fef885d1d1afa49a0e8544ecf436869d F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09 F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30 @@ -1803,7 +1816,7 @@ F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 F test/transitive1.test f8ee983600b33d167da1885657f064aec404e1c0d0bc8765fdf163f4c749237a F test/trigger1.test 02cc64dc98278816c1c1ed8e472e18db8edbad88f37018bf46223e9614831963 -F test/trigger2.test 6e35bd7321c49e63d540aee980eb95dec63e1d1caca175224101045bcc80871f +F test/trigger2.test 30fcb3a6aa6782020d47968735ee6086ed795f73a7affa9406c8d5a36e7b5265 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83 @@ -1829,7 +1842,7 @@ F test/tt3_vacuum.c 71b254cde1fc49d6c8c44efd54f4668f3e57d7b3a8f4601ade069f75a999 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unhex.test 47b547f4b35e4f6525ecac7c7839bd3ae4eb4613d4e8932592eff55da83308f1 +F test/unhex.test b7f1b806207cb77fa31c3e434fe92fba524464e3e9356809bfcc28f15af1a8b7 F test/unionall.test eb9afa030897af75fd2f0dd28354ef63c8a5897b6c76aa1f15acae61a12eabcf F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1 F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 @@ -1857,7 +1870,7 @@ F test/uri.test c1abaaaa28e9422d61e5f3f9cbc8ef993ec49fe802f581520731708561d49384 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 F test/utf16align.test 9fde0bb5d3a821594aa68c6829ab9c5453a084384137ebb9f6153e2d678039da -F test/vacuum-into.test e0e3406845be4cf1b44db354179e5d9437e38bc267e4ac8e8dc617f9c3c903ab +F test/vacuum-into.test 35dc6f79b563f91c61822f61797363e97fed1bf28f1f722688b98d43f1980d76 F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8af520 F test/vacuum3.test d9d9a04ee58c485b94694fd4f68cffaba49c32234fdefe1ac1a622c5e17d4ce3 @@ -1870,7 +1883,7 @@ F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test d4c4281e1679245829db35597817282f60dc513fc39cc5439078f009bd118487 F test/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679 F test/view3.test ad8a8290ee2b55ff6ce66c9ef1ce3f1e47926273a3814e1c425293e128a95456 -F test/vt02.c f4a357c8180d71120ca2b466a8df48d9c40fc50873694840327d9647450485f3 +F test/vt02.c 9f098d11920c832900959d7a2545fd67476d76ea6d4147e0b8ff70e915794e5b F test/vtab1.test 09a72330d0f31eda2ffaa828b06a6b917fb86250ee72de0301570af725774c07 F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e @@ -1927,7 +1940,7 @@ F test/walprotocol2.test 7d3b6b4bf0b12f8007121b1e6ef714bc99101fb3b48e46371df1db8 F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20 F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766cdc F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68 -F test/walseh1.test 82da37763b0d87942dccd191e58321532ce3d44b87ef36e04ff9ce13f382bbae +F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533442b F test/walsetlk.test 34c901443b31ab720afc463f5b236c86ca5c4134402573dce91aa0761de8db5a F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f @@ -1966,11 +1979,11 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2 F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976 F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc -F test/window1.test 1e7e13d36235b9a08fcb9790f2b05383f2f8c9538532b027f455766686926114 +F test/window1.test ccfeaf116afc6a8f748a8122a4f1ee6b69e6bbc5acee61197d3c17167338b100 F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476 F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03 -F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb +F test/window3.test 330733bcca73aba4ddae7a1011f2a2120ef7a0c68d8155854e08677417b8dbd0 F test/window4.tcl 6f85307eb67242b654d051f7da32a996a66aee039a09c5ae358541aa61720742 F test/window4.test fbead87f681400ac07ef3555e0488b544a47d35491f8bf09a7474b6f76ce9b4e F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652821e @@ -2018,6 +2031,7 @@ F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a22270 F tool/build-shell.sh f193b5e3eb4afcb4abbf96bf1475be6cfb74763ee2e50c82bc7ca105e8a136c5 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 +F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca F tool/custom.txt 6cdf298f43e1db4bb91406d14777669b8fb1df790837823fa6754c4308decc27 F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 @@ -2027,7 +2041,7 @@ F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c c129ae2924a48310c7b766810391da9e8fda532b9f6bd3f9a9e3a799a1b42af9 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 -F tool/fuzzershell.c e1d90a03ca790d7c331c2aae08ca46ff435f1ae1faa6cb9cc48f4687c18fdc6e +F tool/fuzzershell.c 41480c8a1e4749351f381431ecfdfceba645396c5d836f8d26b51a33c4a21b33 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a5a4f F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce @@ -2040,9 +2054,9 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 -F tool/mkautoconfamal.sh 7077151b62ecb2848c5b2d36cdbcd8caa0b58f2c12dcdac6e982da39d29d213c +F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x -F tool/mkctimec.tcl c7246946f847d3d6d022f5276650e0290e2aa648793be2fb8c3f206347baa356 x +F tool/mkctimec.tcl 372452e24267dfe1b496eec3992d10c6e5e7d7870a152560cdcfe5404bc8cc04 x F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd F tool/mkmsvcmin.tcl 8897d515ef7f94772322db95a3b6fce6c614d84fe0bdd06ba5a1c786351d5a1d F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef @@ -2074,7 +2088,7 @@ F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a80 F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c2a1 F tool/showwal.c 65ecabae3a2dcff4116301d5a8dbb8c4964814da1b2aff6d85c806a88b71fa4e F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe -F tool/spaceanal.tcl 1b5be34c6223cb1af06da2a10fb77863eb869b1962d055820b0a11cf2336ab45 +F tool/spaceanal.tcl 70c87c04cfd2e77b3e6f21c33ca768296aa8f67d4ab4874786ac8fbb28433477 F tool/speed-check.sh 72dc85b2c0484af971ee3e7d10775f72b4e771e27e162c2099b3bf25517c25fb F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e @@ -2089,6 +2103,7 @@ F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaa F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c 41c586dee84d0b190ad13e0282ed83d4a65ec9fefde9adf4943efdf6558eea7f F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f +F tool/srctree-check.tcl cef630bc4ff21a460d72479c43a42bf1c1ed61897659305c35c8d72e91bcb176 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -2121,8 +2136,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a4f03c22ec13d2f9769ac655ad77ccd906ab8c0ee32df37139bd998c234a7a0f -R b4c830d70f3874dce787a7758a7f4657 +P 8fc2c45558a826a84e6f7e98564573da125a5e2d5c635a85bdeba2abe29fbfa1 678a9728dc6b88d8ef924c86603056df18204bc9a9c4776b9baffd7c5b10c5f2 +R d82fad2576b695fa1705b01577ad2529 U larrybr -Z fb0500fa1bec856f4772f8e430b395b8 +Z 177de2308fc40a7c973a81bd0d935779 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index efe5d09407..d959a7cc17 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8fc2c45558a826a84e6f7e98564573da125a5e2d5c635a85bdeba2abe29fbfa1 \ No newline at end of file +ee58425904b36319e016dc69bb5f141bb3565b1723a97490a4b2cfa16b89fbdf \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index d0b1f7f696..ec45e14331 100644 --- a/src/alter.c +++ b/src/alter.c @@ -446,14 +446,19 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ /* Verify that constraints are still satisfied */ if( pNew->pCheck!=0 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) + || (pTab->tabFlags & TF_Strict)!=0 ){ sqlite3NestedParse(pParse, "SELECT CASE WHEN quick_check GLOB 'CHECK*'" " THEN raise(ABORT,'CHECK constraint failed')" + " WHEN quick_check GLOB 'non-* value in*'" + " THEN raise(ABORT,'type mismatch on DEFAULT')" " ELSE raise(ABORT,'NOT NULL constraint failed')" " END" " FROM pragma_quick_check(%Q,%Q)" - " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'", + " WHERE quick_check GLOB 'CHECK*'" + " OR quick_check GLOB 'NULL*'" + " OR quick_check GLOB 'non-* value in*'", zTab, zDb ); } diff --git a/src/btree.c b/src/btree.c index fa5c47d134..ec4d02d195 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1,4 +1,3 @@ - /* ** 2004 April 6 ** @@ -7493,6 +7492,7 @@ static int rebuildPage( int k; /* Current slot in pCArray->apEnd[] */ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ + assert( nCell>0 ); assert( i(u32)usableSize ){ j = 0; } @@ -7799,6 +7799,7 @@ static int editPage( return SQLITE_OK; editpage_fail: /* Unable to edit this page. Rebuild it from scratch instead. */ + if( nNew<1 ) return SQLITE_CORRUPT_BKPT; populateCellCache(pCArray, iNew, nNew); return rebuildPage(pCArray, iNew, nNew, pPg); } @@ -10458,7 +10459,7 @@ static void checkAppendMsg( ** corresponds to page iPg is already set. */ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); } @@ -10466,7 +10467,7 @@ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ ** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. */ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); } @@ -10480,7 +10481,8 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ - if( iPage>pCheck->nPage || iPage==0 ){ + if( iPage>pCheck->nCkPage || iPage==0 ){ + if( pCheck->nCkPage==0 ) return 0; /* omit reference counting */ checkAppendMsg(pCheck, "invalid page number %u", iPage); return 1; } @@ -10707,6 +10709,7 @@ static int checkTreePage( if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ checkAppendMsg(pCheck, "unable to get the page. error code=%d", rc); + if( rc==SQLITE_IOERR_NOMEM ) pCheck->rc = SQLITE_NOMEM; goto end_of_check; } @@ -10977,18 +10980,23 @@ int sqlite3BtreeIntegrityCheck( sCheck.db = db; sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; - sCheck.nPage = btreePagecount(sCheck.pBt); + sCheck.nCkPage = btreePagecount(sCheck.pBt); sCheck.mxErr = mxErr; sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; - if( sCheck.nPage==0 ){ + if( sCheck.nCkPage==0 ){ goto integrity_ck_cleanup; } - sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); - if( !sCheck.aPgRef ){ - checkOom(&sCheck); - goto integrity_ck_cleanup; + if( bPartial ){ + sCheck.nCkPage = 0; + sCheck.aPgRef = 0; + }else{ + sCheck.aPgRef = sqlite3MallocZero((sCheck.nCkPage / 8)+ 1); + if( !sCheck.aPgRef ){ + checkOom(&sCheck); + goto integrity_ck_cleanup; + } } sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); if( sCheck.heap==0 ){ @@ -10997,7 +11005,7 @@ int sqlite3BtreeIntegrityCheck( } i = PENDING_BYTE_PAGE(pBt); - if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); + if( i<=sCheck.nCkPage ) setPageReferenced(&sCheck, i); /* Check the integrity of the freelist */ @@ -11048,7 +11056,7 @@ int sqlite3BtreeIntegrityCheck( /* Make sure every page in the file is referenced */ if( !bPartial ){ - for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ + for(i=1; i<=sCheck.nCkPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM if( getPageReferenced(&sCheck, i)==0 ){ checkAppendMsg(&sCheck, "Page %u: never used", i); diff --git a/src/btreeInt.h b/src/btreeInt.h index 26a0bc6869..563e15f8ac 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -695,7 +695,7 @@ struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ u8 *aPgRef; /* 1 bit per page in the db (see above) */ - Pgno nPage; /* Number of pages in the database */ + Pgno nCkPage; /* Pages in the database. 0 for partial check */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ diff --git a/src/build.c b/src/build.c index 59e3e23f09..24f5d3f96a 100644 --- a/src/build.c +++ b/src/build.c @@ -2920,6 +2920,17 @@ void sqlite3EndTable( /* Reparse everything to update our internal data structures */ sqlite3VdbeAddParseSchemaOp(v, iDb, sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); + + /* Test for cycles in generated columns and illegal expressions + ** in CHECK constraints and in DEFAULT clauses. */ + if( p->tabFlags & TF_HasGenerated ){ + sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); + } + sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); } /* Add the table to the in-memory representation of the database. diff --git a/src/ctime.c b/src/ctime.c index 03c89ff726..cf761299fe 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -639,6 +639,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS "OMIT_SCHEMA_VERSION_PRAGMAS", #endif +#ifdef SQLITE_OMIT_SEH + "OMIT_SEH", +#endif #ifdef SQLITE_OMIT_SHARED_CACHE "OMIT_SHARED_CACHE", #endif diff --git a/src/dbpage.c b/src/dbpage.c index 32a9ce55bf..73c31f0dab 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -425,7 +425,8 @@ int sqlite3DbpageRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); } diff --git a/src/dbstat.c b/src/dbstat.c index 0a89d05249..c70d806370 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -895,7 +895,8 @@ int sqlite3DbstatRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); } diff --git a/src/expr.c b/src/expr.c index 63c5a8faa9..3eb2c03ac5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -591,6 +591,7 @@ Expr *sqlite3ExprForVectorField( */ pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); if( pRet ){ + ExprSetProperty(pRet, EP_FullSize); pRet->iTable = nField; pRet->iColumn = iField; pRet->pLeft = pVector; @@ -1181,6 +1182,69 @@ Expr *sqlite3ExprFunction( return pNew; } +/* +** Report an error when attempting to use an ORDER BY clause within +** the arguments of a non-aggregate function. +*/ +void sqlite3ExprOrderByAggregateError(Parse *pParse, Expr *p){ + sqlite3ErrorMsg(pParse, + "ORDER BY may not be used with non-aggregate %#T()", p + ); +} + +/* +** Attach an ORDER BY clause to a function call. +** +** functionname( arguments ORDER BY sortlist ) +** \_____________________/ \______/ +** pExpr pOrderBy +** +** The ORDER BY clause is inserted into a new Expr node of type TK_ORDER +** and added to the Expr.pLeft field of the parent TK_FUNCTION node. +*/ +void sqlite3ExprAddFunctionOrderBy( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The function call to which ORDER BY is to be added */ + ExprList *pOrderBy /* The ORDER BY clause to add */ +){ + Expr *pOB; + sqlite3 *db = pParse->db; + if( NEVER(pOrderBy==0) ){ + assert( db->mallocFailed ); + return; + } + if( pExpr==0 ){ + assert( db->mallocFailed ); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + assert( pExpr->op==TK_FUNCTION ); + assert( pExpr->pLeft==0 ); + assert( ExprUseXList(pExpr) ); + if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ + /* Ignore ORDER BY on zero-argument aggregates */ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, + pOrderBy); + return; + } + if( IsWindowFunc(pExpr) ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + + pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0); + if( pOB==0 ){ + sqlite3ExprListDelete(db, pOrderBy); + return; + } + pOB->x.pList = pOrderBy; + assert( ExprUseXList(pOB) ); + pExpr->pLeft = pOB; + ExprSetProperty(pOB, EP_FullSize); +} + /* ** Check to see if a function is usable according to current access ** rules: @@ -1434,11 +1498,7 @@ static int dupedExprStructSize(const Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags || p->op==TK_SELECT_COLUMN -#ifndef SQLITE_OMIT_WINDOWFUNC - || ExprHasProperty(p, EP_WinFunc) -#endif - ){ + if( 0==flags || ExprHasProperty(p, EP_FullSize) ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -1469,56 +1529,93 @@ static int dupedExprNodeSize(const Expr *p, int flags){ /* ** Return the number of bytes required to create a duplicate of the -** expression passed as the first argument. The second argument is a -** mask containing EXPRDUP_XXX flags. +** expression passed as the first argument. ** ** The value returned includes space to create a copy of the Expr struct ** itself and the buffer referred to by Expr.u.zToken, if any. ** -** If the EXPRDUP_REDUCE flag is set, then the return value includes -** space to duplicate all Expr nodes in the tree formed by Expr.pLeft -** and Expr.pRight variables (but not for any structures pointed to or -** descended from the Expr.x.pList or Expr.x.pSelect variables). +** The return value includes space to duplicate all Expr nodes in the +** tree formed by Expr.pLeft and Expr.pRight, but not any other +** substructure such as Expr.x.pList, Expr.x.pSelect, and Expr.y.pWin. */ -static int dupedExprSize(const Expr *p, int flags){ - int nByte = 0; - if( p ){ - nByte = dupedExprNodeSize(p, flags); - if( flags&EXPRDUP_REDUCE ){ - nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags); - } - } +static int dupedExprSize(const Expr *p){ + int nByte; + assert( p!=0 ); + nByte = dupedExprNodeSize(p, EXPRDUP_REDUCE); + if( p->pLeft ) nByte += dupedExprSize(p->pLeft); + if( p->pRight ) nByte += dupedExprSize(p->pRight); + assert( nByte==ROUND8(nByte) ); return nByte; } /* -** This function is similar to sqlite3ExprDup(), except that if pzBuffer -** is not NULL then *pzBuffer is assumed to point to a buffer large enough -** to store the copy of expression p, the copies of p->u.zToken -** (if applicable), and the copies of the p->pLeft and p->pRight expressions, -** if any. Before returning, *pzBuffer is set to the first byte past the -** portion of the buffer copied into by this function. +** An EdupBuf is a memory allocation used to stored multiple Expr objects +** together with their Expr.zToken content. This is used to help implement +** compression while doing sqlite3ExprDup(). The top-level Expr does the +** allocation for itself and many of its decendents, then passes an instance +** of the structure down into exprDup() so that they decendents can have +** access to that memory. */ -static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ +typedef struct EdupBuf EdupBuf; +struct EdupBuf { + u8 *zAlloc; /* Memory space available for storage */ +#ifdef SQLITE_DEBUG + u8 *zEnd; /* First byte past the end of memory */ +#endif +}; + +/* +** This function is similar to sqlite3ExprDup(), except that if pEdupBuf +** is not NULL then it points to memory that can be used to store a copy +** of the input Expr p together with its p->u.zToken (if any). pEdupBuf +** is updated with the new buffer tail prior to returning. +*/ +static Expr *exprDup( + sqlite3 *db, /* Database connection (for memory allocation) */ + const Expr *p, /* Expr tree to be duplicated */ + int dupFlags, /* EXPRDUP_REDUCE for compression. 0 if not */ + EdupBuf *pEdupBuf /* Preallocated storage space, or NULL */ +){ Expr *pNew; /* Value to return */ - u8 *zAlloc; /* Memory space from which to build Expr object */ + EdupBuf sEdupBuf; /* Memory space from which to build Expr object */ u32 staticFlag; /* EP_Static if space not obtained from malloc */ + int nToken = -1; /* Space needed for p->u.zToken. -1 means unknown */ assert( db!=0 ); assert( p ); assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE ); - assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE ); + assert( pEdupBuf==0 || dupFlags==EXPRDUP_REDUCE ); /* Figure out where to write the new Expr structure. */ - if( pzBuffer ){ - zAlloc = *pzBuffer; + if( pEdupBuf ){ + sEdupBuf.zAlloc = pEdupBuf->zAlloc; +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = pEdupBuf->zEnd; +#endif staticFlag = EP_Static; - assert( zAlloc!=0 ); + assert( sEdupBuf.zAlloc!=0 ); + assert( dupFlags==EXPRDUP_REDUCE ); }else{ - zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); + int nAlloc; + if( dupFlags ){ + nAlloc = dupedExprSize(p); + }else if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30NN(p->u.zToken)+1; + nAlloc = EXPR_FULLSIZE + ROUND8(nToken); + }else{ + nToken = 0; + nAlloc = EXPR_FULLSIZE; + } + assert( nAlloc==ROUND8(nAlloc) ); + sEdupBuf.zAlloc = sqlite3DbMallocRawNN(db, nAlloc); +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = sEdupBuf.zAlloc ? sEdupBuf.zAlloc+nAlloc : 0; +#endif + staticFlag = 0; } - pNew = (Expr *)zAlloc; + pNew = (Expr *)sEdupBuf.zAlloc; + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); if( pNew ){ /* Set nNewSize to the size allocated for the structure pointed to @@ -1527,22 +1624,26 @@ static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ ** by the copy of the p->u.zToken string (if any). */ const unsigned nStructSize = dupedExprStructSize(p, dupFlags); - const int nNewSize = nStructSize & 0xfff; - int nToken; - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nToken = sqlite3Strlen30(p->u.zToken) + 1; - }else{ - nToken = 0; + int nNewSize = nStructSize & 0xfff; + if( nToken<0 ){ + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; + }else{ + nToken = 0; + } } if( dupFlags ){ + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= nNewSize+nToken ); assert( ExprHasProperty(p, EP_Reduced)==0 ); - memcpy(zAlloc, p, nNewSize); + memcpy(sEdupBuf.zAlloc, p, nNewSize); }else{ u32 nSize = (u32)exprStructSize(p); - memcpy(zAlloc, p, nSize); + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= EXPR_FULLSIZE+nToken ); + memcpy(sEdupBuf.zAlloc, p, nSize); if( nSizeu.zToken string, if any. */ - if( nToken ){ - char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; + assert( nToken>=0 ); + if( nToken>0 ){ + char *zToken = pNew->u.zToken = (char*)&sEdupBuf.zAlloc[nNewSize]; memcpy(zToken, p->u.zToken, nToken); + nNewSize += nToken; } + sEdupBuf.zAlloc += ROUND8(nNewSize); + + if( ((p->flags|pNew->flags)&(EP_TokenOnly|EP_Leaf))==0 ){ - if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ if( ExprUseXSelect(p) ){ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); }else{ - pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags); + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, + p->op!=TK_ORDER ? dupFlags : 0); } - } - /* Fill in pNew->pLeft and pNew->pRight. */ - if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){ - zAlloc += dupedExprNodeSize(p, dupFlags); - if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ - pNew->pLeft = p->pLeft ? - exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; - pNew->pRight = p->pRight ? - exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; - } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(p, EP_WinFunc) ){ pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); assert( ExprHasProperty(pNew, EP_WinFunc) ); } #endif /* SQLITE_OMIT_WINDOWFUNC */ - if( pzBuffer ){ - *pzBuffer = zAlloc; - } - }else{ - if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ - if( pNew->op==TK_SELECT_COLUMN ){ + + /* Fill in pNew->pLeft and pNew->pRight. */ + if( dupFlags ){ + if( p->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; - assert( p->pRight==0 || p->pRight==p->pLeft - || ExprHasProperty(p->pLeft, EP_Subquery) ); + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); + }else{ + pNew->pLeft = p->pLeft ? + exprDup(db, p->pLeft, EXPRDUP_REDUCE, &sEdupBuf) : 0; + } + pNew->pRight = p->pRight ? + exprDup(db, p->pRight, EXPRDUP_REDUCE, &sEdupBuf) : 0; + }else{ + if( p->op==TK_SELECT_COLUMN ){ + pNew->pLeft = p->pLeft; + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); }else{ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); } @@ -1600,6 +1707,8 @@ static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ } } } + if( pEdupBuf ) memcpy(pEdupBuf, &sEdupBuf, sizeof(sEdupBuf)); + assert( sEdupBuf.zAlloc <= sEdupBuf.zEnd ); return pNew; } @@ -1864,11 +1973,7 @@ Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){ ** initially NULL, then create a new expression list. ** ** The pList argument must be either NULL or a pointer to an ExprList -** obtained from a prior call to sqlite3ExprListAppend(). This routine -** may not be used with an ExprList obtained from sqlite3ExprListDup(). -** Reason: This routine assumes that the number of slots in pList->a[] -** is a power of two. That is true for sqlite3ExprListAppend() returns -** but is not necessarily true from the return value of sqlite3ExprListDup(). +** obtained from a prior call to sqlite3ExprListAppend(). ** ** If a memory allocation error occurs, the entire list is freed and ** NULL is returned. If non-NULL is returned, then it is guaranteed @@ -4252,6 +4357,41 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( } +/* +** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This +** function checks the Parse.pIdxPartExpr list to see if this column +** can be replaced with a constant value. If so, it generates code to +** put the constant value in a register (ideally, but not necessarily, +** register iTarget) and returns the register number. +** +** Or, if the TK_COLUMN cannot be replaced by a constant, zero is +** returned. +*/ +static int exprPartidxExprLookup(Parse *pParse, Expr *pExpr, int iTarget){ + IndexedExpr *p; + for(p=pParse->pIdxPartExpr; p; p=p->pIENext){ + if( pExpr->iColumn==p->iIdxCol && pExpr->iTable==p->iDataCur ){ + Vdbe *v = pParse->pVdbe; + int addr = 0; + int ret; + + if( p->bMaybeNullRow ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNullRow, p->iIdxCur); + } + ret = sqlite3ExprCodeTarget(pParse, p->pExpr, iTarget); + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Affinity, ret, 1, 0, + (const char*)&p->aff, 1); + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeChangeP3(v, addr, ret); + } + return ret; + } + } + return 0; +} + + /* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". @@ -4288,6 +4428,7 @@ expr_code_doover: assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); op = pExpr->op; } + assert( op!=TK_ORDER ); switch( op ){ case TK_AGG_COLUMN: { AggInfo *pAggInfo = pExpr->pAggInfo; @@ -4301,7 +4442,7 @@ expr_code_doover: #ifdef SQLITE_VDBE_COVERAGE /* Verify that the OP_Null above is exercised by tests ** tag-20230325-2 */ - sqlite3VdbeAddOp2(v, OP_NotNull, target, 1); + sqlite3VdbeAddOp3(v, OP_NotNull, target, 1, 20230325); VdbeCoverageNeverTaken(v); #endif break; @@ -4409,6 +4550,11 @@ expr_code_doover: iTab = pParse->iSelfTab - 1; } } + else if( pParse->pIdxPartExpr + && 0!=(r1 = exprPartidxExprLookup(pParse, pExpr, target)) + ){ + return r1; + } assert( ExprUseYTab(pExpr) ); assert( pExpr->y.pTab!=0 ); iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, @@ -6369,6 +6515,12 @@ int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){ assert( pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3WalkExprList(&w, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + assert( pExpr->pLeft->x.pList!=0 ); + sqlite3WalkExprList(&w, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); @@ -6633,14 +6785,41 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ u8 enc = ENC(pParse->db); i = addAggInfoFunc(pParse->db, pAggInfo); if( i>=0 ){ + int nArg; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); pItem = &pAggInfo->aFunc[i]; pItem->pFExpr = pExpr; assert( ExprUseUToken(pExpr) ); + nArg = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; pItem->pFunc = sqlite3FindFunction(pParse->db, - pExpr->u.zToken, - pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); - if( pExpr->flags & EP_Distinct ){ + pExpr->u.zToken, nArg, enc, 0); + assert( pItem->bOBUnique==0 ); + if( pExpr->pLeft + && (pItem->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)==0 + ){ + /* The NEEDCOLL test above causes any ORDER BY clause on + ** aggregate min() or max() to be ignored. */ + ExprList *pOBList; + assert( nArg>0 ); + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + pItem->iOBTab = pParse->nTab++; + pOBList = pExpr->pLeft->x.pList; + assert( pOBList->nExpr>0 ); + if( pOBList->nExpr==1 + && nArg==1 + && sqlite3ExprCompare(0,pOBList->a[0].pExpr, + pExpr->x.pList->a[0].pExpr,0)==0 + ){ + pItem->bOBPayload = 0; + }else{ + pItem->bOBPayload = 1; + } + pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct); + }else{ + pItem->iOBTab = -1; + } + if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){ pItem->iDistinct = pParse->nTab++; }else{ pItem->iDistinct = -1; diff --git a/src/fkey.c b/src/fkey.c index 3142e0ca68..bace1ae5e2 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -858,6 +858,7 @@ static int isSetNullAction(Parse *pParse, FKey *pFKey){ if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull) ){ + assert( (pTop->db->flags & SQLITE_FkNoAction)==0 ); return 1; } } @@ -1052,6 +1053,8 @@ void sqlite3FkCheck( } if( regOld!=0 ){ int eAction = pFKey->aAction[aChange!=0]; + if( (db->flags & SQLITE_FkNoAction) ) eAction = OE_None; + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); /* If this is a deferred FK constraint, or a CASCADE or SET NULL ** action applies, then any foreign key violations caused by @@ -1167,7 +1170,11 @@ int sqlite3FkRequired( /* Check if any parent key columns are being modified. */ for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ - if( p->aAction[1]!=OE_None ) return 2; + if( (pParse->db->flags & SQLITE_FkNoAction)==0 + && p->aAction[1]!=OE_None + ){ + return 2; + } bHaveFK = 1; } } @@ -1217,6 +1224,7 @@ static Trigger *fkActionTrigger( int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ action = pFKey->aAction[iAction]; + if( (db->flags & SQLITE_FkNoAction) ) action = OE_None; if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ return 0; } diff --git a/src/func.c b/src/func.c index 8739035b5b..58ef4fef9c 100644 --- a/src/func.c +++ b/src/func.c @@ -1256,7 +1256,8 @@ static void hexFunc( *(z++) = hexdigits[c&0xf]; } *z = 0; - sqlite3_result_text(context, zHex, n*2, sqlite3_free); + sqlite3_result_text64(context, zHex, (u64)(z-zHex), + sqlite3_free, SQLITE_UTF8); } } @@ -1580,7 +1581,7 @@ static void concatFuncCore( k = sqlite3_value_bytes(argv[i]); if( k>0 ){ const char *v = (const char*)sqlite3_value_text(argv[i]); - if( ALWAYS(v!=0) ){ + if( v!=0 ){ if( j>0 && nSep>0 ){ memcpy(&z[j], zSep, nSep); j += nSep; @@ -1592,7 +1593,7 @@ static void concatFuncCore( } z[j] = 0; assert( j<=n ); - sqlite3_result_text64(context, z, n, sqlite3_free, SQLITE_UTF8); + sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8); } /* @@ -2046,6 +2047,7 @@ static void minMaxFinalize(sqlite3_context *context){ /* ** group_concat(EXPR, ?SEPARATOR?) +** string_agg(EXPR, SEPARATOR) ** ** The SEPARATOR goes before the EXPR string. This is tragic. The ** groupConcatInverse() implementation would have been easier if the @@ -2670,6 +2672,8 @@ void sqlite3RegisterBuiltinFunctions(void){ groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), + WAGGREGATE(string_agg, 2, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), #ifdef SQLITE_CASE_SENSITIVE_LIKE diff --git a/src/json.c b/src/json.c index 253fce9f49..c2129a026e 100644 --- a/src/json.c +++ b/src/json.c @@ -602,7 +602,7 @@ static void jsonResult(JsonString *p){ }else if( jsonForceRCStr(p) ){ sqlite3RCStrRef(p->zBuf); sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, - (void(*)(void*))sqlite3RCStrUnref, + sqlite3RCStrUnref, SQLITE_UTF8); } } @@ -1942,7 +1942,7 @@ static JsonParse *jsonParseCached( /* The input JSON was not found anywhere in the cache. We will need ** to parse it ourselves and generate a new JsonParse object. */ - bJsonRCStr = sqlite3ValueIsOfClass(pJson,(void(*)(void*))sqlite3RCStrUnref); + bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref); p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); if( p==0 ){ sqlite3_result_error_nomem(pCtx); @@ -2156,6 +2156,7 @@ static JsonNode *jsonLookupStep( if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; j += jsonNodeSize(&pRoot[j]); } + if( i==0 && j<=pRoot->n ) break; if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; if( pParse->useMod==0 ) break; assert( pRoot->eU==2 ); @@ -2843,11 +2844,13 @@ static void jsonReplaceNode( break; } if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ - char *zCopy = sqlite3DbStrDup(0, z); + char *zCopy = sqlite3_malloc64( n+1 ); int k; if( zCopy ){ + memcpy(zCopy, z, n); + zCopy[n] = 0; jsonParseAddCleanup(p, sqlite3_free, zCopy); - }else{ + }else{ p->oom = 1; sqlite3_result_error_nomem(pCtx); } @@ -2902,6 +2905,7 @@ static void jsonReplaceFunc( } pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); if( pParse==0 ) return; + pParse->nJPRef++; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); pParse->useMod = 1; @@ -2914,6 +2918,7 @@ static void jsonReplaceFunc( jsonReturnJson(pParse, pParse->aNode, ctx, 1); replace_err: jsonDebugPrintParse(pParse); + jsonParseFree(pParse); } @@ -2948,6 +2953,7 @@ static void jsonSetFunc( } pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); if( pParse==0 ) return; + pParse->nJPRef++; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); bApnd = 0; @@ -2964,9 +2970,8 @@ static void jsonSetFunc( } jsonDebugPrintParse(pParse); jsonReturnJson(pParse, pParse->aNode, ctx, 1); - jsonSetDone: - /* no cleanup required */; + jsonParseFree(pParse); } /* @@ -3122,7 +3127,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : - (void(*)(void*))sqlite3RCStrUnref); + sqlite3RCStrUnref); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -3231,7 +3236,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : - (void(*)(void*))sqlite3RCStrUnref); + sqlite3RCStrUnref); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -3663,7 +3668,7 @@ static int jsonEachFilter( if( z==0 ) return SQLITE_OK; memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; - if( sqlite3ValueIsOfClass(argv[0], (void(*)(void*))sqlite3RCStrUnref) ){ + if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){ p->sParse.zJson = sqlite3RCStrRef((char*)z); }else{ n = sqlite3_value_bytes(argv[0]); @@ -3758,7 +3763,8 @@ static sqlite3_module jsonEachModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* The methods of the json_tree virtual table. */ @@ -3786,7 +3792,8 @@ static sqlite3_module jsonTreeModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* !defined(SQLITE_OMIT_JSON) */ diff --git a/src/loadext.c b/src/loadext.c index e792fa5a98..cfa8ba4ca8 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -730,6 +730,9 @@ void sqlite3CloseExtensions(sqlite3 *db){ ** default so as not to open security holes in older applications. */ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); if( onoff ){ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; @@ -751,7 +754,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ */ typedef struct sqlite3AutoExtList sqlite3AutoExtList; static SQLITE_WSD struct sqlite3AutoExtList { - u32 nExt; /* Number of entries in aExt[] */ + u32 nExt; /* Number of entries in aExt[] */ void (**aExt)(void); /* Pointers to the extension init functions */ } sqlite3Autoext = { 0, 0 }; @@ -779,6 +782,9 @@ int sqlite3_auto_extension( void (*xInit)(void) ){ int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( xInit==0 ) return SQLITE_MISUSE_BKPT; +#endif #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); if( rc ){ @@ -831,6 +837,9 @@ int sqlite3_cancel_auto_extension( int i; int n = 0; wsdAutoextInit; +#ifdef SQLITE_ENABLE_API_ARMOR + if( xInit==0 ) return 0; +#endif sqlite3_mutex_enter(mutex); for(i=(int)wsdAutoext.nExt-1; i>=0; i--){ if( wsdAutoext.aExt[i]==xInit ){ diff --git a/src/main.c b/src/main.c index a43afab168..030b725b1e 100644 --- a/src/main.c +++ b/src/main.c @@ -954,6 +954,10 @@ int sqlite3_db_cacheflush(sqlite3 *db){ int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); va_start(ap, op); switch( op ){ @@ -2365,6 +2369,12 @@ void *sqlite3_preupdate_hook( void *pArg /* First callback argument */ ){ void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || xCallback==0 ){ + return 0; + } +#endif sqlite3_mutex_enter(db->mutex); pRet = db->pPreUpdateArg; db->xPreUpdateCallback = xCallback; @@ -4160,6 +4170,28 @@ int sqlite3_test_control(int op, ...){ } #endif + /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); + ** + ** If b is true, then activate the SQLITE_FkNoAction setting. If b is + ** false then clearn that setting. If the SQLITE_FkNoAction setting is + ** abled, all foreign key ON DELETE and ON UPDATE actions behave as if + ** they were NO ACTION, regardless of how they are defined. + ** + ** NB: One must usually run "PRAGMA writable_schema=RESET" after + ** using this test-control, before it will take full effect. failing + ** to reset the schema can result in some unexpected behavior. + */ + case SQLITE_TESTCTRL_FK_NO_ACTION: { + sqlite3 *db = va_arg(ap, sqlite3*); + int b = va_arg(ap, int); + if( b ){ + db->flags |= SQLITE_FkNoAction; + }else{ + db->flags &= ~SQLITE_FkNoAction; + } + break; + } + /* ** sqlite3_test_control(BITVEC_TEST, size, program) ** @@ -5002,7 +5034,7 @@ int sqlite3_compileoption_used(const char *zOptName){ int nOpt; const char **azCompileOpt; -#if SQLITE_ENABLE_API_ARMOR +#ifdef SQLITE_ENABLE_API_ARMOR if( zOptName==0 ){ (void)SQLITE_MISUSE_BKPT; return 0; diff --git a/src/malloc.c b/src/malloc.c index 48c4600606..356750682e 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -896,5 +896,5 @@ int sqlite3ApiExit(sqlite3* db, int rc){ if( db->mallocFailed || rc ){ return apiHandleError(db, rc); } - return rc & db->errMask; + return 0; } diff --git a/src/mutex.c b/src/mutex.c index 13a9fca15b..381ffbdfd5 100644 --- a/src/mutex.c +++ b/src/mutex.c @@ -133,7 +133,7 @@ static void checkMutexFree(sqlite3_mutex *p){ assert( SQLITE_MUTEX_FAST<2 ); assert( SQLITE_MUTEX_WARNONCONTENTION<2 ); -#if SQLITE_ENABLE_API_ARMOR +#ifdef SQLITE_ENABLE_API_ARMOR if( ((CheckMutex*)p)->iType<2 ) #endif { diff --git a/src/mutex_unix.c b/src/mutex_unix.c index ac4331a67b..beae877f98 100644 --- a/src/mutex_unix.c +++ b/src/mutex_unix.c @@ -223,7 +223,7 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ */ static void pthreadMutexFree(sqlite3_mutex *p){ assert( p->nRef==0 ); -#if SQLITE_ENABLE_API_ARMOR +#ifdef SQLITE_ENABLE_API_ARMOR if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) #endif { diff --git a/src/notify.c b/src/notify.c index 4960ab76b1..6a4cab8755 100644 --- a/src/notify.c +++ b/src/notify.c @@ -152,6 +152,9 @@ int sqlite3_unlock_notify( ){ int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); enterMutex(); diff --git a/src/pager.c b/src/pager.c index a53dc1889a..5c2d556b3e 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1492,9 +1492,32 @@ static int writeJournalHdr(Pager *pPager){ memset(zHeader, 0, sizeof(aJournalMagic)+4); } + + /* The random check-hash initializer */ - sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + } +#ifdef SQLITE_DEBUG + else{ + /* The Pager.cksumInit variable is usually randomized above to protect + ** against there being existing records in the journal file. This is + ** dangerous, as following a crash they may be mistaken for records + ** written by the current transaction and rolled back into the database + ** file, causing corruption. The following assert statements verify + ** that this is not required in "journal_mode=memory" mode, as in that + ** case the journal file is always 0 bytes in size at this point. + ** It is advantageous to avoid the sqlite3_randomness() call if possible + ** as it takes the global PRNG mutex. */ + i64 sz = 0; + sqlite3OsFileSize(pPager->jfd, &sz); + assert( sz==0 ); + assert( pPager->journalOff==journalHdrOffset(pPager) ); + assert( sqlite3JournalIsInMemory(pPager->jfd) ); + } +#endif put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); + /* The initial database size */ put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); /* The assumed sector size for this process */ @@ -2138,6 +2161,9 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ return (rc==SQLITE_OK?rc2:rc); } +/* Forward reference */ +static int pager_playback(Pager *pPager, int isHot); + /* ** Execute a rollback if a transaction is active and unlock the ** database file. @@ -2166,6 +2192,21 @@ static void pagerUnlockAndRollback(Pager *pPager){ assert( pPager->eState==PAGER_READER ); pager_end_transaction(pPager, 0, 0); } + }else if( pPager->eState==PAGER_ERROR + && pPager->journalMode==PAGER_JOURNALMODE_MEMORY + && isOpen(pPager->jfd) + ){ + /* Special case for a ROLLBACK due to I/O error with an in-memory + ** journal: We have to rollback immediately, before the journal is + ** closed, because once it is closed, all content is forgotten. */ + int errCode = pPager->errCode; + u8 eLock = pPager->eLock; + pPager->eState = PAGER_OPEN; + pPager->errCode = SQLITE_OK; + pPager->eLock = EXCLUSIVE_LOCK; + pager_playback(pPager, 1); + pPager->errCode = errCode; + pPager->eLock = eLock; } pager_unlock(pPager); } @@ -5658,8 +5699,20 @@ int sqlite3PagerGet( DbPage **ppPage, /* Write a pointer to the page here */ int flags /* PAGER_GET_XXX flags */ ){ - /* printf("PAGE %u\n", pgno); fflush(stdout); */ +#if 0 /* Trace page fetch by setting to 1 */ + int rc; + printf("PAGE %u\n", pgno); + fflush(stdout); + rc = pPager->xGet(pPager, pgno, ppPage, flags); + if( rc ){ + printf("PAGE %u failed with 0x%02x\n", pgno, rc); + fflush(stdout); + } + return rc; +#else + /* Normal, high-speed version of sqlite3PagerGet() */ return pPager->xGet(pPager, pgno, ppPage, flags); +#endif } /* @@ -7346,7 +7399,7 @@ int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ } assert( state==pPager->eState ); } - }else if( eMode==PAGER_JOURNALMODE_OFF ){ + }else if( eMode==PAGER_JOURNALMODE_OFF || eMode==PAGER_JOURNALMODE_MEMORY ){ sqlite3OsClose(pPager->jfd); } } diff --git a/src/parse.y b/src/parse.y index 867b62aa7a..19491192e3 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1144,6 +1144,10 @@ expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. { expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP. { A = sqlite3ExprFunction(pParse, Y, &X, D); } +expr(A) ::= idj(X) LP distinct(D) exprlist(Y) ORDER BY sortlist(O) RP. { + A = sqlite3ExprFunction(pParse, Y, &X, D); + sqlite3ExprAddFunctionOrderBy(pParse, A, O); +} expr(A) ::= idj(X) LP STAR RP. { A = sqlite3ExprFunction(pParse, 0, &X, 0); } @@ -1153,6 +1157,11 @@ expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP filter_over(Z). { A = sqlite3ExprFunction(pParse, Y, &X, D); sqlite3WindowAttach(pParse, A, Z); } +expr(A) ::= idj(X) LP distinct(D) exprlist(Y) ORDER BY sortlist(O) RP filter_over(Z). { + A = sqlite3ExprFunction(pParse, Y, &X, D); + sqlite3WindowAttach(pParse, A, Z); + sqlite3ExprAddFunctionOrderBy(pParse, A, O); +} expr(A) ::= idj(X) LP STAR RP filter_over(Z). { A = sqlite3ExprFunction(pParse, 0, &X, 0); sqlite3WindowAttach(pParse, A, Z); diff --git a/src/pragma.c b/src/pragma.c index a4e05bbdf6..cbf5b0b455 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1124,7 +1124,11 @@ void sqlite3Pragma( #endif if( sqlite3GetBoolean(zRight, 0) ){ - db->flags |= mask; + if( (mask & SQLITE_WriteSchema)==0 + || (db->flags & SQLITE_Defensive)==0 + ){ + db->flags |= mask; + } }else{ db->flags &= ~mask; if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; @@ -1762,6 +1766,11 @@ void sqlite3Pragma( sqlite3_vtab *pVTab; int a1; if( !IsVirtual(pTab) ) continue; + if( pTab->nCol<=0 ){ + const char *zMod = pTab->u.vtab.azArg[0]; + if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; + } + sqlite3ViewGetColumnNames(pParse, pTab); if( pTab->u.vtab.p==0 ) continue; pVTab = pTab->u.vtab.p->pVtab; if( NEVER(pVTab==0) ) continue; @@ -2900,7 +2909,8 @@ static const sqlite3_module pragmaVtabModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff --git a/src/prepare.c b/src/prepare.c index 9f843faa86..d3e134e764 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -598,8 +598,6 @@ void sqlite3ParseObjectReset(Parse *pParse){ db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; assert( pParse->db->pParse==pParse ); db->pParse = pParse->pOuterParse; - pParse->db = 0; - pParse->disableLookaside = 0; } /* diff --git a/src/printf.c b/src/printf.c index 87ad91f795..3c0b182d39 100644 --- a/src/printf.c +++ b/src/printf.c @@ -1389,7 +1389,7 @@ char *sqlite3RCStrRef(char *z){ ** Decrease the reference count by one. Free the string when the ** reference count reaches zero. */ -void sqlite3RCStrUnref(char *z){ +void sqlite3RCStrUnref(void *z){ RCStr *p = (RCStr*)z; assert( p!=0 ); p--; diff --git a/src/resolve.c b/src/resolve.c index bd890c9f8d..0072f6b6aa 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1052,6 +1052,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); + assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); zId = pExpr->u.zToken; pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ @@ -1193,6 +1194,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pNC->nNcErr++; } #endif + else if( is_agg==0 && pExpr->pLeft ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + pNC->nNcErr++; + } if( is_agg ){ /* Window functions may not be arguments of aggregate functions. ** Or arguments of other window functions. But aggregate functions @@ -1211,6 +1216,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif sqlite3WalkExprList(pWalker, pList); if( is_agg ){ + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ Select *pSel = pNC->pWinSelect; @@ -1774,10 +1784,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ while( p ){ assert( (p->selFlags & SF_Expanded)!=0 ); assert( (p->selFlags & SF_Resolved)==0 ); - assert( db->suppressErr==0 ); /* SF_Resolved not set if errors suppressed */ p->selFlags |= SF_Resolved; - /* Resolve the expressions in the LIMIT and OFFSET clauses. These ** are not allowed to refer to any names, so pass an empty NameContext. */ diff --git a/src/select.c b/src/select.c index a55545d513..29df3325f3 100644 --- a/src/select.c +++ b/src/select.c @@ -454,6 +454,7 @@ static void unsetJoinExpr(Expr *p, int iTable, int nullable){ } if( p->op==TK_FUNCTION ){ assert( ExprUseXList(p) ); + assert( p->pLeft==0 ); if( p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ @@ -6490,8 +6491,14 @@ static void analyzeAggFuncArgs( pNC->ncFlags |= NC_InAggFunc; for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( pExpr->op==TK_FUNCTION || pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3ExprAnalyzeAggList(pNC, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC assert( !IsWindowFunc(pExpr) ); if( ExprHasProperty(pExpr, EP_WinFunc) ){ @@ -6646,6 +6653,32 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ pFunc->pFunc->zName)); } } + if( pFunc->iOBTab>=0 ){ + ExprList *pOBList; + KeyInfo *pKeyInfo; + int nExtra = 0; + assert( pFunc->pFExpr->pLeft!=0 ); + assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pFunc->pFExpr->pLeft) ); + pOBList = pFunc->pFExpr->pLeft->x.pList; + if( !pFunc->bOBUnique ){ + nExtra++; /* One extra column for the OP_Sequence */ + } + if( pFunc->bOBPayload ){ + /* extra columns for the function arguments */ + assert( ExprUseXList(pFunc->pFExpr) ); + nExtra += pFunc->pFExpr->x.pList->nExpr; + } + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); + if( !pFunc->bOBUnique && pParse->nErr==0 ){ + pKeyInfo->nKeyField++; + } + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iOBTab, pOBList->nExpr+nExtra, 0, + (char*)pKeyInfo, P4_KEYINFO); + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(ORDER BY)", + pFunc->pFunc->zName)); + } } } @@ -6661,13 +6694,46 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; + if( pF->iOBTab>=0 ){ + /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and + ** all content was stored in emphermal table pF->iOBTab. Extract that + ** content now (in ORDER BY order) and make all calls to OP_AggStep + ** before doing the OP_AggFinal call. */ + int iTop; /* Start of loop for extracting columns */ + int nArg; /* Number of columns to extract */ + int nKey; /* Key columns to be skipped */ + int regAgg; /* Extract into this array */ + int j; /* Loop counter */ + + nArg = pList->nExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + + if( pF->bOBPayload==0 ){ + nKey = 0; + }else{ + assert( pF->pFExpr->pLeft!=0 ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + assert( pF->pFExpr->pLeft->x.pList!=0 ); + nKey = pF->pFExpr->pLeft->x.pList->nExpr; + if( !pF->bOBUnique ) nKey++; + } + iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); + } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, iTop); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + } sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), pList ? pList->nExpr : 0); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); } } - /* ** Generate code that will update the accumulator memory cells for an ** aggregate based on the current cursor position. @@ -6676,6 +6742,13 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ ** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator ** registers if register regAcc contains 0. The caller will take care ** of setting and clearing regAcc. +** +** For an ORDER BY aggregate, the actually accumulator memory cell update +** is deferred until after all input rows have been received, so that they +** can be run in the requested order. In that case, instead of invoking +** OP_AggStep to update accumulator, just add the arguments that would +** have been passed into OP_AggStep into the sorting ephemeral table +** (along with the appropriate sort key). */ static void updateAccumulator( Parse *pParse, @@ -6697,6 +6770,7 @@ static void updateAccumulator( int nArg; int addrNext = 0; int regAgg; + int regAggSz = 0; ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); assert( !IsWindowFunc(pF->pFExpr) ); @@ -6723,7 +6797,39 @@ static void updateAccumulator( addrNext = sqlite3VdbeMakeLabel(pParse); sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); } - if( pList ){ + if( pF->iOBTab>=0 ){ + /* Instead of invoking AggStep, we must push the arguments that would + ** have been passed to AggStep onto the sorting table. */ + int jj; /* Registered used so far in building the record */ + ExprList *pOBList; /* The ORDER BY clause */ + assert( pList!=0 ); + nArg = pList->nExpr; + assert( nArg>0 ); + assert( pF->pFExpr->pLeft!=0 ); + assert( pF->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + pOBList = pF->pFExpr->pLeft->x.pList; + assert( pOBList!=0 ); + assert( pOBList->nExpr>0 ); + regAggSz = pOBList->nExpr; + if( !pF->bOBUnique ){ + regAggSz++; /* One register for OP_Sequence */ + } + if( pF->bOBPayload ){ + regAggSz += nArg; + } + regAggSz++; /* One extra register to hold result of MakeRecord */ + regAgg = sqlite3GetTempRange(pParse, regAggSz); + sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP); + jj = pOBList->nExpr; + if( !pF->bOBUnique ){ + sqlite3VdbeAddOp2(v, OP_Sequence, pF->iOBTab, regAgg+jj); + jj++; + } + if( pF->bOBPayload ){ + sqlite3ExprCodeExprList(pParse, pList, regAgg+jj, 0, SQLITE_ECEL_DUP); + } + }else if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); @@ -6738,24 +6844,35 @@ static void updateAccumulator( pF->iDistinct = codeDistinct(pParse, eDistinctType, pF->iDistinct, addrNext, pList, regAgg); } - if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ - CollSeq *pColl = 0; - struct ExprList_item *pItem; - int j; - assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ - for(j=0, pItem=pList->a; !pColl && jpExpr); + if( pF->iOBTab>=0 ){ + /* Insert a new record into the ORDER BY table */ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regAgg, regAggSz-1, + regAgg+regAggSz-1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pF->iOBTab, regAgg+regAggSz-1, + regAgg, regAggSz-1); + sqlite3ReleaseTempRange(pParse, regAgg, regAggSz); + }else{ + /* Invoke the AggStep function */ + if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl = 0; + struct ExprList_item *pItem; + int j; + assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ + for(j=0, pItem=pList->a; !pColl && jpExpr); + } + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, + (char *)pColl, P4_COLLSEQ); } - if( !pColl ){ - pColl = pParse->db->pDfltColl; - } - if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; - sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); } - sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); - sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); - sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } diff --git a/src/shell.c.in b/src/shell.c.in index 2d382a681a..50f78acca8 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -455,7 +455,6 @@ static int stdin_is_interactive = 1; static int console_utf8 = sizeof(char*)/4 - 1; #else # define SHELL_WIN_UTF8_OPT 0 - static const int console_utf8 = 0; #endif /* @@ -1229,7 +1228,7 @@ static void shellDtostr( char z[400]; if( n<1 ) n = 1; if( n>350 ) n = 350; - sprintf(z, "%#+.*e", n, r); + snprintf(z, sizeof(z)-1, "%#+.*e", n, r); sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); } @@ -8034,7 +8033,6 @@ static int do_meta_command(char *zLine, ShellState *p){ azArg[nArg++] = &zLine[h]; while( zLine[h] && !IsSpace(zLine[h]) ){ h++; } if( zLine[h] ) zLine[h++] = 0; - resolve_backslashes(azArg[nArg-1]); } } azArg[nArg] = 0; @@ -8773,8 +8771,10 @@ static int do_meta_command(char *zLine, ShellState *p){ "SELECT rowid FROM sqlite_schema" " WHERE name GLOB 'sqlite_stat[134]'", -1, &pStmt, 0); - doStats = sqlite3_step(pStmt)==SQLITE_ROW; - sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ){ + doStats = sqlite3_step(pStmt)==SQLITE_ROW; + sqlite3_finalize(pStmt); + } } if( doStats==0 ){ raw_printf(p->out, "/* No STAT tables available */\n"); @@ -10910,6 +10910,7 @@ static int do_meta_command(char *zLine, ShellState *p){ {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/ + {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" }, {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" }, {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" }, @@ -10980,6 +10981,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, db, int) */ case SQLITE_TESTCTRL_OPTIMIZATIONS: + case SQLITE_TESTCTRL_FK_NO_ACTION: if( nArg==3 ){ unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 2d351008dc..b915ef4fb7 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8245,6 +8245,7 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ +#define SQLITE_TESTCTRL_FK_NO_ACTION 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 @@ -10610,6 +10611,13 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. ** +** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set, +** the returned buffer content will remain accessible and unchanged +** until either the next write operation on the connection or when +** the connection is closed, and applications must not modify the +** buffer. If the bit had been clear, the returned buffer will not +** be accessed by SQLite after the call. +** ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. @@ -10658,6 +10666,9 @@ unsigned char *sqlite3_serialize( ** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. ** +** Applications must not modify the buffer P or invalidate it before +** the database connection D is closed. +** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. @@ -10666,6 +10677,13 @@ unsigned char *sqlite3_serialize( ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** +** The deserialized database should not be in [WAL mode]. If the database +** is in WAL mode, then any attempt to use the database file will result +** in an [SQLITE_CANTOPEN] error. The application can set the +** [file format version numbers] (bytes 18 and 19) of the input database P +** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the +** database file into rollback mode and work around this limitation. +** ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 225e54800b..b6cc81fba1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -318,6 +318,16 @@ # endif #endif +/* +** Enable SQLITE_USE_SEH by default on MSVC builds. Only omit +** SEH support if the -DSQLITE_OMIT_SEH option is given. +*/ +#if defined(_MSC_VER) && !defined(SQLITE_OMIT_SEH) +# define SQLITE_USE_SEH 1 +#else +# undef SQLITE_USE_SEH +#endif + /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never @@ -1835,6 +1845,7 @@ struct sqlite3 { /* the count using a callback. */ #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ #define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */ +#define SQLITE_FkNoAction HI(0x00008) /* Treat all FK as NO ACTION */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG @@ -2850,6 +2861,9 @@ struct AggInfo { FuncDef *pFunc; /* The aggregate function implementation */ int iDistinct; /* Ephemeral table used to enforce DISTINCT */ int iDistAddr; /* Address of OP_OpenEphemeral */ + int iOBTab; /* Ephemeral table to implement ORDER BY */ + u8 bOBPayload; /* iOBTab has payload columns separate from key */ + u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ @@ -3034,7 +3048,7 @@ struct Expr { #define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ #define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ - /* 0x020000 // Available for reuse */ +#define EP_FullSize 0x020000 /* Expr structure must remain full sized */ #define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */ #define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ @@ -3064,6 +3078,7 @@ struct Expr { #define ExprClearProperty(E,P) (E)->flags&=~(P) #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) +#define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) /* Macros used to ensure that the correct members of unions are accessed ** in Expr. @@ -3790,6 +3805,7 @@ struct Parse { int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ + IndexedExpr *pIdxPartExpr; /* Exprs constrained by index WHERE clauses */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ @@ -4775,6 +4791,8 @@ void sqlite3PExprAddSelect(Parse*, Expr*, Select*); Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); Expr *sqlite3ExprSimplifiedAndOr(Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int); +void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*); +void sqlite3ExprOrderByAggregateError(Parse*,Expr*); void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); @@ -5341,7 +5359,7 @@ int sqlite3ApiExit(sqlite3 *db, int); int sqlite3OpenTempDatabase(Parse *); char *sqlite3RCStrRef(char*); -void sqlite3RCStrUnref(char*); +void sqlite3RCStrUnref(void*); char *sqlite3RCStrNew(u64); char *sqlite3RCStrResize(char*,u64); diff --git a/src/test1.c b/src/test1.c index 145882f087..55be0596b0 100644 --- a/src/test1.c +++ b/src/test1.c @@ -4222,9 +4222,11 @@ static int SQLITE_TCLAPI test_bind_value_from_preupdate( sqlite3_stmt *pStmt; int idx; int bidx; +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK const char *z3 = 0; sqlite3 *db = 0; sqlite3_value *pVal = 0; +#endif if( objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "STMT N NEW|OLD IDX"); @@ -4233,11 +4235,11 @@ static int SQLITE_TCLAPI test_bind_value_from_preupdate( if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; - z3 = Tcl_GetString(objv[3]); if( Tcl_GetIntFromObj(interp, objv[4], &bidx) ) return TCL_ERROR; - db = sqlite3_db_handle(pStmt); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK + z3 = Tcl_GetString(objv[3]); + db = sqlite3_db_handle(pStmt); if( z3[0]=='n' ){ sqlite3_preupdate_new(db, bidx, &pVal); }else if( z3[0]=='o' ){ @@ -7651,6 +7653,7 @@ static int SQLITE_TCLAPI test_test_control( { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER }, { "SQLITE_TESTCTRL_INTERNAL_FUNCTIONS", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS}, + { "SQLITE_TESTCTRL_FK_NO_ACTION", SQLITE_TESTCTRL_FK_NO_ACTION}, { 0, 0 } }; int iVerb; @@ -7690,6 +7693,20 @@ static int SQLITE_TCLAPI test_test_control( break; } + case SQLITE_TESTCTRL_FK_NO_ACTION: { + int val = 0; + sqlite3 *db = 0; + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 2, objv, "DB BOOLEAN"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; + if( Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; + + sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, db, val); + break; + } + case SQLITE_TESTCTRL_SORTER_MMAP: { int val; sqlite3 *db; diff --git a/src/test8.c b/src/test8.c index f0f5743101..4aeb555c76 100644 --- a/src/test8.c +++ b/src/test8.c @@ -1317,7 +1317,12 @@ static sqlite3_module echoModule = { echoCommit, /* xCommit - commit transaction */ echoRollback, /* xRollback - rollback transaction */ echoFindFunction, /* xFindFunction - function overloading */ - echoRename /* xRename - rename the table */ + echoRename, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; static sqlite3_module echoModuleV2 = { @@ -1343,7 +1348,9 @@ static sqlite3_module echoModuleV2 = { echoRename, /* xRename - rename the table */ echoSavepoint, echoRelease, - echoRollbackTo + echoRollbackTo, + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff --git a/src/test_bestindex.c b/src/test_bestindex.c index f6e0678ce0..8128530b40 100644 --- a/src/test_bestindex.c +++ b/src/test_bestindex.c @@ -814,6 +814,11 @@ static sqlite3_module tclModule = { 0, /* xRollback */ tclFindFunction, /* xFindFunction */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff --git a/src/test_fs.c b/src/test_fs.c index ddfdc7fb59..f88f3a9425 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -816,6 +816,11 @@ static sqlite3_module fsModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; static sqlite3_module fsdirModule = { @@ -839,6 +844,11 @@ static sqlite3_module fsdirModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; static sqlite3_module fstreeModule = { @@ -862,6 +872,11 @@ static sqlite3_module fstreeModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff --git a/src/test_intarray.c b/src/test_intarray.c index 8c74a04156..a978ed585d 100644 --- a/src/test_intarray.c +++ b/src/test_intarray.c @@ -205,6 +205,11 @@ static sqlite3_module intarrayModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ diff --git a/src/test_osinst.c b/src/test_osinst.c index 3e698c0324..062e83159b 100644 --- a/src/test_osinst.c +++ b/src/test_osinst.c @@ -1090,7 +1090,12 @@ int sqlite3_vfslog_register(sqlite3 *db){ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ - }; + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ + }; sqlite3_create_module(db, "vfslog", &vfslog_module, 0); return SQLITE_OK; diff --git a/src/test_schema.c b/src/test_schema.c index d2cae7f2aa..2cbc18e2b2 100644 --- a/src/test_schema.c +++ b/src/test_schema.c @@ -292,6 +292,11 @@ static sqlite3_module schemaModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ diff --git a/src/test_tclvar.c b/src/test_tclvar.c index bf99a8eadb..36165bc27d 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -487,6 +487,11 @@ static sqlite3_module tclvarModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff --git a/src/treeview.c b/src/treeview.c index d55adab384..1fad8673dd 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -412,6 +412,7 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ sqlite3TreeViewItem(pView, "FILTER", 1); sqlite3TreeViewExpr(pView, pWin->pFilter, 0); sqlite3TreeViewPop(&pView); + if( pWin->eFrmType==TK_FILTER ) return; } sqlite3TreeViewPush(&pView, more); if( pWin->zName ){ @@ -421,7 +422,7 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ } if( pWin->zBase ) nElement++; if( pWin->pOrderBy ) nElement++; - if( pWin->eFrmType ) nElement++; + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ) nElement++; if( pWin->eExclude ) nElement++; if( pWin->zBase ){ sqlite3TreeViewPush(&pView, (--nElement)>0); @@ -434,7 +435,7 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ if( pWin->pOrderBy ){ sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY"); } - if( pWin->eFrmType ){ + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ){ char zBuf[30]; const char *zFrmType = "ROWS"; if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE"; @@ -682,7 +683,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ assert( ExprUseXList(pExpr) ); pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC - pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0; + pWin = IsWindowFunc(pExpr) ? pExpr->y.pWin : 0; #else pWin = 0; #endif @@ -708,7 +709,13 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } if( pFarg ){ - sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); + sqlite3TreeViewExprList(pView, pFarg, pWin!=0 || pExpr->pLeft, 0); + if( pExpr->pLeft ){ + Expr *pOB = pExpr->pLeft; + assert( pOB->op==TK_ORDER ); + assert( ExprUseXList(pOB) ); + sqlite3TreeViewExprList(pView, pOB->x.pList, pWin!=0, "ORDERBY"); + } } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ @@ -717,6 +724,10 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ #endif break; } + case TK_ORDER: { + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, "ORDERBY"); + break; + } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: { assert( ExprUseXSelect(pExpr) ); diff --git a/src/trigger.c b/src/trigger.c index bcb2132f0b..2decea8206 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -183,6 +183,10 @@ void sqlite3BeginTrigger( sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_orphan_error; } + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on shadow tables"); + goto trigger_orphan_error; + } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ diff --git a/src/util.c b/src/util.c index 58591590dc..e9c7cccb03 100644 --- a/src/util.c +++ b/src/util.c @@ -1367,121 +1367,32 @@ u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ ** this function assumes the single-byte case has already been handled. */ u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ - u32 a,b; + u64 v64; + u8 n; - /* The 1-byte case. Overwhelmingly the most common. Handled inline - ** by the getVarin32() macro */ - a = *p; - /* a: p0 (unmasked) */ -#ifndef getVarint32 - if (!(a&0x80)) - { - /* Values between 0 and 127 */ - *v = a; - return 1; - } -#endif + /* Assume that the single-byte case has already been handled by + ** the getVarint32() macro */ + assert( (p[0] & 0x80)!=0 ); - /* The 2-byte case */ - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 128 and 16383 */ - a &= 0x7f; - a = a<<7; - *v = a | b; + if( (p[1] & 0x80)==0 ){ + /* This is the two-byte case */ + *v = ((p[0]&0x7f)<<7) | p[1]; return 2; } - - /* The 3-byte case */ - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 16384 and 2097151 */ - a &= (0x7f<<14)|(0x7f); - b &= 0x7f; - b = b<<7; - *v = a | b; + if( (p[2] & 0x80)==0 ){ + /* This is the three-byte case */ + *v = ((p[0]&0x7f)<<14) | ((p[1]&0x7f)<<7) | p[2]; return 3; } - - /* A 32-bit varint is used to store size information in btrees. - ** Objects are rarely larger than 2MiB limit of a 3-byte varint. - ** A 3-byte varint is sufficient, for example, to record the size - ** of a 1048569-byte BLOB or string. - ** - ** We only unroll the first 1-, 2-, and 3- byte cases. The very - ** rare larger cases can be handled by the slower 64-bit varint - ** routine. - */ -#if 1 - { - u64 v64; - u8 n; - - n = sqlite3GetVarint(p-2, &v64); - assert( n>3 && n<=9 ); - if( (v64 & SQLITE_MAX_U32)!=v64 ){ - *v = 0xffffffff; - }else{ - *v = (u32)v64; - } - return n; - } - -#else - /* For following code (kept for historical record only) shows an - ** unrolling for the 3- and 4-byte varint cases. This code is - ** slightly faster, but it is also larger and much harder to test. - */ - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 2097152 and 268435455 */ - b &= (0x7f<<14)|(0x7f); - a &= (0x7f<<14)|(0x7f); - a = a<<7; - *v = a | b; - return 4; - } - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 268435456 and 34359738367 */ - a &= SLOT_4_2_0; - b &= SLOT_4_2_0; - b = b<<7; - *v = a | b; - return 5; - } - - /* We can only reach this point when reading a corrupt database - ** file. In that case we are not in any hurry. Use the (relatively - ** slow) general-purpose sqlite3GetVarint() routine to extract the - ** value. */ - { - u64 v64; - u8 n; - - p -= 4; - n = sqlite3GetVarint(p, &v64); - assert( n>5 && n<=9 ); + /* four or more bytes */ + n = sqlite3GetVarint(p, &v64); + assert( n>3 && n<=9 ); + if( (v64 & SQLITE_MAX_U32)!=v64 ){ + *v = 0xffffffff; + }else{ *v = (u32)v64; - return n; } -#endif + return n; } /* diff --git a/src/vdbe.c b/src/vdbe.c index 6463136507..b7bf8c0ec7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -762,11 +762,11 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow( sqlite3RCStrRef(pBuf); if( t&1 ){ rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding, - (void(*)(void*))sqlite3RCStrUnref); + sqlite3RCStrUnref); pDest->flags |= MEM_Term; }else{ rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, - (void(*)(void*))sqlite3RCStrUnref); + sqlite3RCStrUnref); } }else{ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest); @@ -6906,13 +6906,33 @@ case OP_CreateBtree: { /* out2 */ /* Opcode: SqlExec * * * P4 * ** ** Run the SQL statement or statements specified in the P4 string. +** Disable Auth and Trace callbacks while those statements are running if +** P1 is true. */ case OP_SqlExec: { + char *zErr; + sqlite3_xauth xAuth; + u8 mTrace; + sqlite3VdbeIncrWriteCounter(p, 0); db->nSqlExec++; - rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); + zErr = 0; + xAuth = db->xAuth; + mTrace = db->mTrace; + if( pOp->p1 ){ + db->xAuth = 0; + db->mTrace = 0; + } + rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); db->nSqlExec--; - if( rc ) goto abort_due_to_error; + db->xAuth = xAuth; + db->mTrace = mTrace; + if( zErr || rc ){ + sqlite3VdbeError(p, "%s", zErr); + sqlite3_free(zErr); + if( rc==SQLITE_NOMEM ) goto no_mem; + goto abort_due_to_error; + } break; } diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 1213dbe6d1..31ebbc6976 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -375,7 +375,7 @@ void sqlite3_value_free(sqlite3_value *pOld){ ** is too big or if an OOM occurs. ** ** The invokeValueDestructor(P,X) routine invokes destructor function X() -** on value P is not going to be used and need to be destroyed. +** on value P if P is not going to be used and need to be destroyed. */ static void setResultStrOrError( sqlite3_context *pCtx, /* Function context */ @@ -405,7 +405,7 @@ static void setResultStrOrError( static int invokeValueDestructor( const void *p, /* Value to destroy */ void (*xDel)(void*), /* The destructor */ - sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if not NULL */ ){ assert( xDel!=SQLITE_DYNAMIC ); if( xDel==0 ){ @@ -415,7 +415,14 @@ static int invokeValueDestructor( }else{ xDel((void*)p); } +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx!=0 ){ + sqlite3_result_error_toobig(pCtx); + } +#else + assert( pCtx!=0 ); sqlite3_result_error_toobig(pCtx); +#endif return SQLITE_TOOBIG; } void sqlite3_result_blob( @@ -424,6 +431,12 @@ void sqlite3_result_blob( int n, void (*xDel)(void *) ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 || n<0 ){ + invokeValueDestructor(z, xDel, pCtx); + return; + } +#endif assert( n>=0 ); assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, 0, xDel); @@ -434,8 +447,14 @@ void sqlite3_result_blob64( sqlite3_uint64 n, void (*xDel)(void *) ){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); }else{ @@ -443,30 +462,48 @@ void sqlite3_result_blob64( } } void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); } void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); } void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } void sqlite3_result_null(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } @@ -476,14 +513,25 @@ void sqlite3_result_pointer( const char *zPType, void (*xDestructor)(void*) ){ - Mem *pOut = pCtx->pOut; + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(pPtr, xDestructor, 0); + return; + } +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); sqlite3VdbeMemRelease(pOut); pOut->flags = MEM_Null; sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); } void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ - Mem *pOut = pCtx->pOut; + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); pOut->eSubtype = eSubtype & 0xff; pOut->flags |= MEM_Subtype; @@ -494,6 +542,12 @@ void sqlite3_result_text( int n, void (*xDel)(void *) ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } @@ -504,6 +558,12 @@ void sqlite3_result_text64( void (*xDel)(void *), unsigned char enc ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); if( enc!=SQLITE_UTF8 ){ @@ -547,7 +607,16 @@ void sqlite3_result_text16le( } #endif /* SQLITE_OMIT_UTF16 */ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ - Mem *pOut = pCtx->pOut; + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; + if( pValue==0 ){ + sqlite3_result_null(pCtx); + return; + } +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemCopy(pOut, pValue); sqlite3VdbeChangeEncoding(pOut, pCtx->enc); @@ -559,7 +628,12 @@ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); } int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ - Mem *pOut = pCtx->pOut; + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return SQLITE_MISUSE_BKPT; +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(pCtx); @@ -573,6 +647,9 @@ int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ #endif } void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif pCtx->isError = errCode ? errCode : -1; #ifdef SQLITE_DEBUG if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; @@ -585,6 +662,9 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ /* Force an SQLITE_TOOBIG error. */ void sqlite3_result_error_toobig(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_TOOBIG; sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, @@ -593,6 +673,9 @@ void sqlite3_result_error_toobig(sqlite3_context *pCtx){ /* An SQLITE_NOMEM error. */ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM_BKPT; @@ -845,7 +928,11 @@ int sqlite3_step(sqlite3_stmt *pStmt){ ** pointer to it. */ void *sqlite3_user_data(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p && p->pFunc ); +#endif return p->pFunc->pUserData; } @@ -860,7 +947,11 @@ void *sqlite3_user_data(sqlite3_context *p){ ** application defined function. */ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p && p->pOut ); +#endif return p->pOut->db; } @@ -879,7 +970,11 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ ** value, as a signal to the xUpdate routine that the column is unchanged. */ int sqlite3_vtab_nochange(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p ); +#endif return sqlite3_value_nochange(p->pOut); } @@ -1038,6 +1133,9 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return 0; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #if SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 0; @@ -1070,8 +1168,12 @@ void sqlite3_set_auxdata( void (*xDelete)(void*) ){ AuxData *pAuxData; - Vdbe *pVdbe = pCtx->pVdbe; + Vdbe *pVdbe; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pVdbe= pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #ifdef SQLITE_ENABLE_STAT4 if( pVdbe==0 ) goto failed; @@ -1737,6 +1839,9 @@ int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){ int rc; Vdbe *p = (Vdbe *)pStmt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(p->db->mutex); if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){ rc = SQLITE_TOOBIG; @@ -1863,6 +1968,9 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ Vdbe *v = (Vdbe*)pStmt; int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(v->db->mutex); if( ((int)v->explain)==eMode ){ rc = SQLITE_OK; @@ -2029,10 +2137,16 @@ static UnpackedRecord *vdbeUnpackRecord( ** a field of the row currently being updated or deleted. */ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; Mem *pMem; int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; /* Test that this call is being made from within an SQLITE_DELETE or ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ if( !p || p->op==SQLITE_INSERT ){ @@ -2093,7 +2207,12 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ ** the number of columns in the row being updated, deleted or inserted. */ int sqlite3_preupdate_count(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->keyinfo.nKeyField : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -2111,7 +2230,12 @@ int sqlite3_preupdate_count(sqlite3 *db){ ** or SET DEFAULT action is considered a trigger. */ int sqlite3_preupdate_depth(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->v->nFrame : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -2122,7 +2246,12 @@ int sqlite3_preupdate_depth(sqlite3 *db){ ** only. */ int sqlite3_preupdate_blobwrite(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->iBlobWrite : -1); } #endif @@ -2133,10 +2262,16 @@ int sqlite3_preupdate_blobwrite(sqlite3 *db){ ** a field of the row currently being updated or inserted. */ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; int rc = SQLITE_OK; Mem *pMem; +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; if( !p || p->op==SQLITE_DELETE ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_new_out; @@ -2215,11 +2350,20 @@ int sqlite3_stmt_scanstatus_v2( void *pOut /* OUT: Write the answer here */ ){ Vdbe *p = (Vdbe*)pStmt; - VdbeOp *aOp = p->aOp; - int nOp = p->nOp; + VdbeOp *aOp; + int nOp; ScanStatus *pScan = 0; int idx; +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 || pOut==0 + || iScanStatusOpSQLITE_SCANSTAT_NCYCLE ){ + return 1; + } +#endif + aOp = p->aOp; + nOp = p->nOp; if( p->pFrame ){ VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); @@ -2366,7 +2510,7 @@ int sqlite3_stmt_scanstatus( void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; int ii; - for(ii=0; iinOp; ii++){ + for(ii=0; p!=0 && iinOp; ii++){ Op *pOp = &p->aOp[ii]; pOp->nExec = 0; pOp->nCycle = 0; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index eafc038562..27be95a6b5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1002,6 +1002,10 @@ void sqlite3VdbeNoJumpsOutsideSubrtn( int iDest = pOp->p2; /* Jump destination */ if( iDest==0 ) continue; if( pOp->opcode==OP_Gosub ) continue; + if( pOp->p3==20230325 && pOp->opcode==OP_NotNull ){ + /* This is a deliberately taken illegal branch. tag-20230325-2 */ + continue; + } if( iDest<0 ){ int j = ADDR(iDest); assert( j>=0 ); @@ -4461,6 +4465,16 @@ SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ return n1 - n2; } +/* The following two functions are used only within testcase() to prove +** test coverage. These functions do no exist for production builds. +** We must use separate SQLITE_NOINLINE functions here, since otherwise +** optimizer code movement causes gcov to become very confused. +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +static int SQLITE_NOINLINE doubleLt(double a, double b){ return ar ); testcase( x==r ); - if( xr; /*NO_TEST*/ /* work around bug in gcov */ + return (xr); }else{ i64 y; double s; @@ -4482,12 +4495,11 @@ int sqlite3IntFloatCompare(i64 i, double r){ y = (i64)r; if( iy ) return +1; - testcase( r<(double)i ); - testcase( r>(double)i ); - testcase( r==(double)i ); s = (double)i; - if( sr; /*NO_TEST*/ /* work around bug in gcov */ + testcase( doubleLt(s,r) ); + testcase( doubleLt(r,s) ); + testcase( doubleEq(r,s) ); + return (sr); } } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 32987da137..522447dbc1 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -59,8 +59,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ /* Set the value of register r[1] in the SQL statement to integer iRow. ** This is done directly as a performance optimization */ - v->aMem[1].flags = MEM_Int; - v->aMem[1].u.i = iRow; + sqlite3VdbeMemSetInt64(&v->aMem[1], iRow); /* If the statement has been run before (and is paused at the OP_ResultRow) ** then back it up to the point where it does the OP_NotExists. This could @@ -143,7 +142,7 @@ int sqlite3_blob_open( #endif *ppBlob = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ + if( !sqlite3SafetyCheckOk(db) || zTable==0 || zColumn==0 ){ return SQLITE_MISUSE_BKPT; } #endif diff --git a/src/vdbemem.c b/src/vdbemem.c index e25efc9771..eee828143a 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -336,7 +336,7 @@ void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ pMem->flags |= MEM_Term; return; } - if( pMem->xDel==(void(*)(void*))sqlite3RCStrUnref ){ + if( pMem->xDel==sqlite3RCStrUnref ){ /* Blindly assume that all RCStr objects are zero-terminated */ pMem->flags |= MEM_Term; return; @@ -1716,6 +1716,7 @@ static int valueFromExpr( if( pVal ){ pVal->flags = MEM_Int; pVal->u.i = pExpr->u.zToken[4]==0; + sqlite3ValueApplyAffinity(pVal, affinity, enc); } } diff --git a/src/vdbesort.c b/src/vdbesort.c index 2b7da94f7f..0083690308 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -186,7 +186,7 @@ struct SorterFile { struct SorterList { SorterRecord *pList; /* Linked list of records */ u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ - int szPMA; /* Size of pList as PMA in bytes */ + i64 szPMA; /* Size of pList as PMA in bytes */ }; /* @@ -295,10 +295,10 @@ typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int); struct SortSubtask { SQLiteThread *pThread; /* Background thread, if any */ int bDone; /* Set if thread is finished but not joined */ + int nPMA; /* Number of PMAs currently in file */ VdbeSorter *pSorter; /* Sorter that owns this sub-task */ UnpackedRecord *pUnpacked; /* Space to unpack a record */ SorterList list; /* List for thread to write to a PMA */ - int nPMA; /* Number of PMAs currently in file */ SorterCompare xCompare; /* Compare function to use */ SorterFile file; /* Temp file for level-0 PMAs */ SorterFile file2; /* Space for other PMAs */ @@ -1772,8 +1772,8 @@ int sqlite3VdbeSorterWrite( int rc = SQLITE_OK; /* Return Code */ SorterRecord *pNew; /* New list element */ int bFlush; /* True to flush contents of memory to PMA */ - int nReq; /* Bytes of memory required */ - int nPMA; /* Bytes of PMA space required */ + i64 nReq; /* Bytes of memory required */ + i64 nPMA; /* Bytes of PMA space required */ int t; /* serial type of first record field */ assert( pCsr->eCurType==CURTYPE_SORTER ); diff --git a/src/vdbevtab.c b/src/vdbevtab.c index 59030e0e12..b295dff7b6 100644 --- a/src/vdbevtab.c +++ b/src/vdbevtab.c @@ -428,7 +428,8 @@ static sqlite3_module bytecodevtabModule = { /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; diff --git a/src/where.c b/src/where.c index 3a865d3f19..05ae24f7bc 100644 --- a/src/where.c +++ b/src/where.c @@ -1142,13 +1142,17 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ int iCur; /* Cursor for table getting the filter */ IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */ + IndexedExpr *saved_pIdxPartExpr; /* saved copy of Parse.pIdxPartExpr */ saved_pIdxEpr = pParse->pIdxEpr; + saved_pIdxPartExpr = pParse->pIdxPartExpr; pParse->pIdxEpr = 0; + pParse->pIdxPartExpr = 0; assert( pLoop!=0 ); assert( v!=0 ); assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ); addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); do{ @@ -1238,6 +1242,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( }while( iLevel < pWInfo->nLevel ); sqlite3VdbeJumpHere(v, addrOnce); pParse->pIdxEpr = saved_pIdxEpr; + pParse->pIdxPartExpr = saved_pIdxPartExpr; } @@ -3497,6 +3502,100 @@ static SQLITE_NOINLINE u32 whereIsCoveringIndex( return rc; } +/* +** This is an sqlite3ParserAddCleanup() callback that is invoked to +** free the Parse->pIdxEpr list when the Parse object is destroyed. +*/ +static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ + IndexedExpr **pp = (IndexedExpr**)pObject; + while( *pp!=0 ){ + IndexedExpr *p = *pp; + *pp = p->pIENext; + sqlite3ExprDelete(db, p->pExpr); + sqlite3DbFreeNN(db, p); + } +} + +/* +** This function is called for a partial index - one with a WHERE clause - in +** two scenarios. In both cases, it determines whether or not the WHERE +** clause on the index implies that a column of the table may be safely +** replaced by a constant expression. For example, in the following +** SELECT: +** +** CREATE INDEX i1 ON t1(b, c) WHERE a=; +** SELECT a, b, c FROM t1 WHERE a= AND b=?; +** +** The "a" in the select-list may be replaced by , iff: +** +** (a) is a constant expression, and +** (b) The (a=) comparison uses the BINARY collation sequence, and +** (c) Column "a" has an affinity other than NONE or BLOB. +** +** If argument pItem is NULL, then pMask must not be NULL. In this case this +** function is being called as part of determining whether or not pIdx +** is a covering index. This function clears any bits in (*pMask) +** corresponding to columns that may be replaced by constants as described +** above. +** +** Otherwise, if pItem is not NULL, then this function is being called +** as part of coding a loop that uses index pIdx. In this case, add entries +** to the Parse.pIdxPartExpr list for each column that can be replaced +** by a constant. +*/ +static void wherePartIdxExpr( + Parse *pParse, /* Parse context */ + Index *pIdx, /* Partial index being processed */ + Expr *pPart, /* WHERE clause being processed */ + Bitmask *pMask, /* Mask to clear bits in */ + int iIdxCur, /* Cursor number for index */ + SrcItem *pItem /* The FROM clause entry for the table */ +){ + assert( pItem==0 || (pItem->fg.jointype & JT_RIGHT)==0 ); + assert( (pItem==0 || pMask==0) && (pMask!=0 || pItem!=0) ); + + if( pPart->op==TK_AND ){ + wherePartIdxExpr(pParse, pIdx, pPart->pRight, pMask, iIdxCur, pItem); + pPart = pPart->pLeft; + } + + if( (pPart->op==TK_EQ || pPart->op==TK_IS) ){ + Expr *pLeft = pPart->pLeft; + Expr *pRight = pPart->pRight; + u8 aff; + + if( pLeft->op!=TK_COLUMN ) return; + if( !sqlite3ExprIsConstant(pRight) ) return; + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; + if( pLeft->iColumn<0 ) return; + aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; + if( aff>=SQLITE_AFF_TEXT ){ + if( pItem ){ + sqlite3 *db = pParse->db; + IndexedExpr *p = (IndexedExpr*)sqlite3DbMallocRaw(db, sizeof(*p)); + if( p ){ + int bNullRow = (pItem->fg.jointype&(JT_LEFT|JT_LTORJ))!=0; + p->pExpr = sqlite3ExprDup(db, pRight, 0); + p->iDataCur = pItem->iCursor; + p->iIdxCur = iIdxCur; + p->iIdxCol = pLeft->iColumn; + p->bMaybeNullRow = bNullRow; + p->pIENext = pParse->pIdxPartExpr; + p->aff = aff; + pParse->pIdxPartExpr = p; + if( p->pIENext==0 ){ + void *pArg = (void*)&pParse->pIdxPartExpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); + } + } + }else if( pLeft->iColumn<(BMS-1) ){ + *pMask &= ~((Bitmask)1 << pLeft->iColumn); + } + } + } +} + + /* ** Add all WhereLoop objects for a single table of the join where the table ** is identified by pBuilder->pNew->iTab. That table is guaranteed to be @@ -3712,6 +3811,11 @@ static int whereLoopAddBtree( pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; }else{ m = pSrc->colUsed & pProbe->colNotIdxed; + if( pProbe->pPartIdxWhere ){ + wherePartIdxExpr( + pWInfo->pParse, pProbe, pProbe->pPartIdxWhere, &m, 0, 0 + ); + } pNew->wsFlags = WHERE_INDEXED; if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); @@ -5667,20 +5771,6 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( } } -/* -** This is an sqlite3ParserAddCleanup() callback that is invoked to -** free the Parse->pIdxEpr list when the Parse object is destroyed. -*/ -static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ - Parse *pParse = (Parse*)pObject; - while( pParse->pIdxEpr!=0 ){ - IndexedExpr *p = pParse->pIdxEpr; - pParse->pIdxEpr = p->pIENext; - sqlite3ExprDelete(db, p->pExpr); - sqlite3DbFreeNN(db, p); - } -} - /* ** The index pIdx is used by a query and contains one or more expressions. ** In other words pIdx is an index on an expression. iIdxCur is the cursor @@ -5742,7 +5832,8 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( #endif pParse->pIdxEpr = p; if( p->pIENext==0 ){ - sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse); + void *pArg = (void*)&pParse->pIdxEpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); } } } @@ -6354,6 +6445,11 @@ WhereInfo *sqlite3WhereBegin( if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); } + if( pIx->pPartIdxWhere && (pTabItem->fg.jointype & JT_RIGHT)==0 ){ + wherePartIdxExpr( + pParse, pIx, pIx->pPartIdxWhere, 0, iIndexCur, pTabItem + ); + } } pLevel->iIdxCur = iIndexCur; assert( pIx!=0 ); diff --git a/src/window.c b/src/window.c index d46eabc3b4..2c449592d7 100644 --- a/src/window.c +++ b/src/window.c @@ -1312,8 +1312,9 @@ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ if( p ){ assert( p->op==TK_FUNCTION ); assert( pWin ); + assert( ExprIsFullSize(p) ); p->y.pWin = pWin; - ExprSetProperty(p, EP_WinFunc); + ExprSetProperty(p, EP_WinFunc|EP_FullSize); pWin->pOwner = p; if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){ sqlite3ErrorMsg(pParse, diff --git a/test/aggnested.test b/test/aggnested.test index 1b8b608803..5f033a246c 100644 --- a/test/aggnested.test +++ b/test/aggnested.test @@ -25,19 +25,19 @@ do_test aggnested-1.1 { INSERT INTO t1 VALUES(1), (2), (3); CREATE TABLE t2(b1 INTEGER); INSERT INTO t2 VALUES(4), (5); - SELECT (SELECT group_concat(a1,'x') FROM t2) FROM t1; + SELECT (SELECT string_agg(a1,'x') FROM t2) FROM t1; } } {1x2x3} do_test aggnested-1.2 { db eval { SELECT - (SELECT group_concat(a1,'x') || '-' || group_concat(b1,'y') FROM t2) + (SELECT string_agg(a1,'x') || '-' || string_agg(b1,'y') FROM t2) FROM t1; } } {1x2x3-4y5} do_test aggnested-1.3 { db eval { - SELECT (SELECT group_concat(b1,a1) FROM t2) FROM t1; + SELECT (SELECT string_agg(b1,a1) FROM t2) FROM t1; } } {415 425 435} do_test aggnested-1.4 { @@ -309,7 +309,7 @@ do_execsql_test 5.4 { do_execsql_test 5.5 { CREATE TABLE a(b); WITH c AS(SELECT a) - SELECT(SELECT(SELECT group_concat(b, b) + SELECT(SELECT(SELECT string_agg(b, b) LIMIT(SELECT 0.100000 * AVG(DISTINCT(SELECT 0 FROM a ORDER BY b, b, b)))) FROM a GROUP BY b, diff --git a/test/aggorderby.test b/test/aggorderby.test new file mode 100644 index 0000000000..bf77a7d4cf --- /dev/null +++ b/test/aggorderby.test @@ -0,0 +1,79 @@ +# 2023-10-18 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements tests for ORDER BY on aggregate functions. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test aggorderby-1.1 { + CREATE TABLE t1(a TEXT,b INT,c INT,d INT); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<9) + INSERT INTO t1(a,b,c,d) SELECT printf('%d',(x*7)%10),1,x,10-x FROM c; + INSERT INTO t1(a,b,c,d) SELECT a, 2, c, 10-d FROM t1; + CREATE INDEX t1b ON t1(b); +} +do_catchsql_test aggorderby-1.2 { + SELECT b, group_concat(a ORDER BY max(d)) FROM t1 GROUP BY b; +} {1 {misuse of aggregate function max()}} +do_catchsql_test aggorderby-1.3 { + SELECT abs(a ORDER BY max(d)) FROM t1; +} {1 {ORDER BY may not be used with non-aggregate abs()}} + +do_execsql_test aggorderby-2.0 { + SELECT group_concat(a ORDER BY a) FROM t1 WHERE b=1; +} {0,1,2,3,4,5,6,7,8,9} +do_execsql_test aggorderby-2.1 { + SELECT group_concat(a ORDER BY c) FROM t1 WHERE b=1; +} {0,7,4,1,8,5,2,9,6,3} +do_execsql_test aggorderby-2.2 { + SELECT group_concat(a ORDER BY b, d) FROM t1; +} {3,6,9,2,5,8,1,4,7,0,0,7,4,1,8,5,2,9,6,3} +do_execsql_test aggorderby-2.3 { + SELECT string_agg(a, ',' ORDER BY b DESC, d) FROM t1; +} {0,7,4,1,8,5,2,9,6,3,3,6,9,2,5,8,1,4,7,0} +do_execsql_test aggorderby-2.4 { + SELECT b, group_concat(a ORDER BY d) FROM t1 GROUP BY b ORDER BY b; +} {1 3,6,9,2,5,8,1,4,7,0 2 0,7,4,1,8,5,2,9,6,3} + +do_execsql_test aggorderby-3.0 { + SELECT group_concat(DISTINCT a ORDER BY a) FROM t1; +} {0,1,2,3,4,5,6,7,8,9} +do_execsql_test aggorderby-3.1 { + SELECT group_concat(DISTINCT a ORDER BY c) FROM t1; +} {0,7,4,1,8,5,2,9,6,3} + +do_execsql_test aggorderby-4.0 { + SELECT count(ORDER BY a) FROM t1; +} 20 +do_execsql_test aggorderby-4.1 { + SELECT c, max(a ORDER BY a) FROM t1; +} {7 9} + + +do_execsql_test aggorderby-5.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t3; + CREATE TABLE t1(a TEXT); INSERT INTO t1 VALUES('aaa'),('bbb'); + CREATE TABLE t3(d TEXT); INSERT INTO t3 VALUES('/'),('-'); + SELECT (SELECT string_agg(a,d) FROM t3) FROM t1; +} {aaa-aaa bbb-bbb} +do_execsql_test aggorderby-5.1 { + SELECT (SELECT group_concat(a,d ORDER BY d) FROM t3) FROM t1; +} {aaa/aaa bbb/bbb} +do_execsql_test aggorderby-5.2 { + SELECT (SELECT string_agg(a,d ORDER BY d DESC) FROM t3) FROM t1; +} {aaa-aaa bbb-bbb} +do_execsql_test aggorderby-5.3 { + SELECT (SELECT string_agg(a,'#' ORDER BY d) FROM t3) FROM t1; +} {aaa#aaa bbb#bbb} + +finish_test diff --git a/test/alter.test b/test/alter.test index 0088858a15..ee8e6c0b90 100644 --- a/test/alter.test +++ b/test/alter.test @@ -934,5 +934,24 @@ do_execsql_test alter-19.3 { SELECT name FROM sqlite_schema WHERE sql LIKE '%t3%' ORDER BY name; } {r1 t3} +# 2023-10-14 +# On an ALTER TABLE ADD COLUMN with a DEFAULT clause on a STRICT table +# make sure that the DEFAULT has a compatible type. +# +reset_db +do_execsql_test alter-20.1 { + CREATE TABLE t1(a INT) STRICT; + INSERT INTO t1(a) VALUES(45); +} {} +do_catchsql_test alter-20.2 { + ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT x'313233'; +} {1 {type mismatch on DEFAULT}} +do_execsql_test alter-20.2 { + DELETE FROM t1; + ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT x'313233'; +} {} +do_catchsql_test alter-20.3 { + INSERT INTO t1(a) VALUES(45); +} {1 {cannot store BLOB value in TEXT column t1.b}} finish_test diff --git a/test/altercol.test b/test/altercol.test index e39793aa9f..f44aa2e065 100644 --- a/test/altercol.test +++ b/test/altercol.test @@ -343,6 +343,21 @@ do_catchsql_test 8.4.5 { ALTER TABLE b1 RENAME a TO aaa; } {1 {error in view zzz: no such column: george}} +do_execsql_test 8.5 { + DROP VIEW zzz; + CREATE TABLE t5(a TEXT, b INT); + INSERT INTO t5(a,b) VALUES('aaa',7),('bbb',3),('ccc',4); + CREATE VIEW vt5(x) AS SELECT group_concat(a ORDER BY b) FROM t5; + SELECT x FROM vt5; +} {bbb,ccc,aaa} +do_execsql_test 8.5.1 { + ALTER TABLE t5 RENAME COLUMN b TO bbb; + SELECT sql FROM sqlite_schema WHERE name='vt5'; +} {{CREATE VIEW vt5(x) AS SELECT group_concat(a ORDER BY bbb) FROM t5}} +do_execsql_test 8.5.2 { + SELECT x FROM vt5; +} {bbb,ccc,aaa} + #------------------------------------------------------------------------- # More triggers. # diff --git a/test/alterqf.test b/test/alterqf.test index 423a9fa865..b248c7c7f4 100644 --- a/test/alterqf.test +++ b/test/alterqf.test @@ -65,7 +65,7 @@ foreach {tn before after} { 11 {CREATE TRIGGER ott AFTER UPDATE ON t1 BEGIN SELECT max("str", new."a") FROM t1 - WHERE group_concat("b", ",") OVER (ORDER BY c||"str"); + WHERE string_agg("b", ",") OVER (ORDER BY c||"str"); UPDATE t1 SET c= b + "str"; DELETE FROM t1 WHERE EXISTS ( SELECT 1 FROM t1 AS o WHERE o."a" = "o.a" AND t1.b IN("t1.b") @@ -73,7 +73,7 @@ foreach {tn before after} { END; } {CREATE TRIGGER ott AFTER UPDATE ON t1 BEGIN SELECT max('str', new."a") FROM t1 - WHERE group_concat("b", ',') OVER (ORDER BY c||'str'); + WHERE string_agg("b", ',') OVER (ORDER BY c||'str'); UPDATE t1 SET c= b + 'str'; DELETE FROM t1 WHERE EXISTS ( SELECT 1 FROM t1 AS o WHERE o."a" = 'o.a' AND t1.b IN('t1.b') diff --git a/test/altertrig.test b/test/altertrig.test index 934a636669..556dc3fea4 100644 --- a/test/altertrig.test +++ b/test/altertrig.test @@ -160,4 +160,3 @@ foreach {tn alter update final} { } finish_test - diff --git a/test/bestindex9.test b/test/bestindex9.test index 94b9da0d38..d591b30efe 100644 --- a/test/bestindex9.test +++ b/test/bestindex9.test @@ -102,7 +102,3 @@ do_bestindex9_test 4 { finish_test - - - - diff --git a/test/bestindexA.test b/test/bestindexA.test index 650404eaa0..1976986471 100644 --- a/test/bestindexA.test +++ b/test/bestindexA.test @@ -133,6 +133,3 @@ do_xbestindex_test 1.9 { finish_test - - - diff --git a/test/changes.test b/test/changes.test index 21db075f96..b3a2ae1eef 100644 --- a/test/changes.test +++ b/test/changes.test @@ -86,5 +86,3 @@ foreach {tn nRow wor} { } finish_test - - diff --git a/test/changes2.test b/test/changes2.test index 46e25c03a7..5b2684a8df 100644 --- a/test/changes2.test +++ b/test/changes2.test @@ -92,4 +92,3 @@ do_execsql_test 2.4 { } {{2 changes} {2 changes}} finish_test - diff --git a/test/dbfuzz001.test b/test/dbfuzz001.test index 2a430de12e..228dd16db6 100644 --- a/test/dbfuzz001.test +++ b/test/dbfuzz001.test @@ -371,4 +371,27 @@ do_catchsql_test dbfuzz001-330 { } {1 {database disk image is malformed}} extra_schema_checks 1 +#------------------------------------------------------------------------- +reset_db + +do_execsql_test dbfuzz001-430 { + CREATE TABLE t1(a INTEGER, b INT, c DEFAULT 0); +} + +do_execsql_test dbfuzz001-420 { + PRAGMA locking_mode=EXCLUSIVE; + PRAGMA journal_mode = memory; + INSERT INTO t1 VALUES(1,2,3); + PRAGMA journal_mode=PERSIST; +} {exclusive memory persist} + +do_execsql_test dbfuzz001-430 { + INSERT INTO t1 VALUES(4, 5, 6); +} + +do_execsql_test dbfuzz001-440 { + PRAGMA journal_mode=MEMORY; + INSERT INTO t1 VALUES(7, 8, 9); +} {memory} + finish_test diff --git a/test/dbpagefault.test b/test/dbpagefault.test index 544d279ce9..f27741cba1 100644 --- a/test/dbpagefault.test +++ b/test/dbpagefault.test @@ -84,5 +84,3 @@ do_catchsql_test 3.2 { finish_test - - diff --git a/test/distinctagg.test b/test/distinctagg.test index 6e46c88616..199ca0666e 100644 --- a/test/distinctagg.test +++ b/test/distinctagg.test @@ -56,7 +56,7 @@ do_test distinctagg-2.1 { } {1 {DISTINCT aggregates must have exactly one argument}} do_test distinctagg-2.2 { catchsql { - SELECT group_concat(distinct a,b) FROM t1; + SELECT string_agg(distinct a,b) FROM t1; } } {1 {DISTINCT aggregates must have exactly one argument}} @@ -215,4 +215,3 @@ do_execsql_test 7.0 { finish_test - diff --git a/test/e_expr.test b/test/e_expr.test index 5ad5993bb4..0db63a8ac4 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1930,7 +1930,7 @@ foreach {tn expr restype resval} { 6 { ( SELECT y FROM t4 ORDER BY y DESC ) } text two 7 { ( SELECT sum(x) FROM t4 ) } integer 6 - 8 { ( SELECT group_concat(y,'') FROM t4 ) } text onetwothree + 8 { ( SELECT string_agg(y,'') FROM t4 ) } text onetwothree 9 { ( SELECT max(x) FROM t4 WHERE y LIKE '___') } integer 2 } { diff --git a/test/e_select.test b/test/e_select.test index 5a3f0d30dc..e2e969dcf9 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -943,7 +943,7 @@ do_select_tests e_select-4.6 { 4 "SELECT *, count(*) FROM a1 JOIN a2" {1 1 1 1 16} 5 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {1 1 1 3} 6 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {1 1 1 3} - 7 "SELECT group_concat(three, ''), a1.* FROM a1 NATURAL JOIN a2" {12 1 1} + 7 "SELECT string_agg(three, ''), a1.* FROM a1 NATURAL JOIN a2" {12 1 1} } # EVIDENCE-OF: R-04486-07266 Or, if the dataset contains zero rows, then diff --git a/test/filter2.test b/test/filter2.test index 21ee6659ff..06cfd2a4c3 100644 --- a/test/filter2.test +++ b/test/filter2.test @@ -113,7 +113,7 @@ do_execsql_test 1.12 { do_execsql_test 1.13 { SELECT - group_concat(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=0), + string_agg(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=0), group_concat(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=1), count(*) FILTER (WHERE b%2!=0), count(*) FILTER (WHERE b%2!=1) diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index 74aaa18fb8..433a486359 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -2595,17 +2595,13 @@ do_execsql_test 17.1 { UPDATE t1 SET b=quote(zeroblob(200)) WHERE a MATCH 'thread*'; } -do_catchsql_test 17.2 { - DROP TABLE IF EXISTS t1; -} {1 {SQL logic error}} - -do_execsql_test 17.3 { +do_execsql_test 17.2 { INSERT INTO t1(t1) VALUES('optimize'); } -do_catchsql_test 17.4 { +do_catchsql_test 17.3 { DROP TABLE IF EXISTS t1; -} {1 {SQL logic error}} +} {0 {}} #------------------------------------------------------------------------- reset_db diff --git a/test/fts3fuzz001.test b/test/fts3fuzz001.test index 41b22d33da..6b1ae90ee4 100644 --- a/test/fts3fuzz001.test +++ b/test/fts3fuzz001.test @@ -13,6 +13,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix fts3fuzz001 ifcapable !deserialize||!fts3 { finish_test @@ -110,5 +111,31 @@ do_test fts3fuzz001-121 { } } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 200 { + CREATE VIRTUAL TABLE x1 USING fts3(x); + + INSERT INTO x1 VALUES('braes brag bragged bragger bragging'); + INSERT INTO x1 VALUES('brags braid braided braiding braids'); + INSERT INTO x1 VALUES('brain brainchild brained braining brains'); + INSERT INTO x1 VALUES('brainstem brainstems brainstorm brainstorms'); + INSERT INTO x1(x1) VALUES('nodesize=24'); +} + +do_execsql_test 210 { + PRAGMA integrity_check; +} {ok} + +do_execsql_test 220 { + INSERT INTO x1(x1) VALUES('merge=10,2') +} + +do_execsql_test 220 { + PRAGMA integrity_check; +} {ok} + + + finish_test diff --git a/test/fts4merge.test b/test/fts4merge.test index 3cd693209d..ffef0e9334 100644 --- a/test/fts4merge.test +++ b/test/fts4merge.test @@ -37,7 +37,7 @@ foreach mod {fts3 fts4} { do_test 1.0 { fts3_build_db_1 -module $mod 1004 } {} do_test 1.1 { fts3_integrity_check t1 } {ok} do_execsql_test 1.1 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level + SELECT level, string_agg(idx, ' ') FROM t1_segdir GROUP BY level } { 0 {0 1 2 3 4 5 6 7 8 9 10 11} 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} @@ -67,7 +67,7 @@ foreach mod {fts3 fts4} { } do_execsql_test 1.5 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level + SELECT level, string_agg(idx, ' ') FROM t1_segdir GROUP BY level } { 3 0 } @@ -103,7 +103,7 @@ foreach mod {fts3 fts4} { do_test 3.1 { fts3_integrity_check t2 } {ok} do_execsql_test 3.2 { - SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level + SELECT level, string_agg(idx, ' ') FROM t2_segdir GROUP BY level } { 0 {0 1 2 3 4 5 6} 1 {0 1 2 3 4} @@ -132,7 +132,7 @@ foreach mod {fts3 fts4} { foreach x {a c b d e f g h i j k l m n o p} { execsql "INSERT INTO t4 VALUES('[string repeat $x 600]')" } - execsql {SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level} + execsql {SELECT level, string_agg(idx, ' ') FROM t4_segdir GROUP BY level} } {0 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}} foreach {tn expect} { @@ -160,7 +160,7 @@ foreach mod {fts3 fts4} { do_execsql_test 4.4.2 { DELETE FROM t4_stat WHERE rowid=1; INSERT INTO t4(t4) VALUES('merge=1,12'); - SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level; + SELECT level, string_agg(idx, ' ') FROM t4_segdir GROUP BY level; } "0 {0 1 2 3 4 5} 1 0" @@ -194,7 +194,7 @@ foreach mod {fts3 fts4} { do_execsql_test 5.3 { INSERT INTO t1(t1) VALUES('merge=1,5'); INSERT INTO t1(t1) VALUES('merge=1,5'); - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + SELECT level, string_agg(idx, ' ') FROM t1_segdir GROUP BY level; } { 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14} 2 {0 1 2 3} @@ -249,7 +249,7 @@ foreach mod {fts3 fts4} { do_execsql_test 5.11 { INSERT INTO t1(t1) VALUES('merge=1,6'); - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + SELECT level, string_agg(idx, ' ') FROM t1_segdir GROUP BY level; SELECT quote(value) from t1_stat WHERE rowid=1; } { 1 {0 1} 2 0 3 0 X'010E' diff --git a/test/func.test b/test/func.test index aea372e08e..883950a0c4 100644 --- a/test/func.test +++ b/test/func.test @@ -1136,18 +1136,18 @@ ifcapable deprecated { } {3} } -# The group_concat() function. +# The group_concat() and string_agg() functions. # do_test func-24.1 { execsql { - SELECT group_concat(t1) FROM tbl1 + SELECT group_concat(t1), string_agg(t1,',') FROM tbl1 } -} {this,program,is,free,software} +} {this,program,is,free,software this,program,is,free,software} do_test func-24.2 { execsql { - SELECT group_concat(t1,' ') FROM tbl1 + SELECT group_concat(t1,' '), string_agg(t1,' ') FROM tbl1 } -} {{this program is free software}} +} {{this program is free software} {this program is free software}} do_test func-24.3 { execsql { SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1 @@ -1160,9 +1160,9 @@ do_test func-24.4 { } {{}} do_test func-24.5 { execsql { - SELECT group_concat(t1,NULL) FROM tbl1 + SELECT group_concat(t1,NULL), string_agg(t1,NULL) FROM tbl1 } -} {thisprogramisfreesoftware} +} {thisprogramisfreesoftware thisprogramisfreesoftware} do_test func-24.6 { execsql { SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 6b434f6bbf..3e34180071 100644 Binary files a/test/fuzzdata8.db and b/test/fuzzdata8.db differ diff --git a/test/gcfault.test b/test/gcfault.test index d54b78fafc..2d77f9ef2c 100644 --- a/test/gcfault.test +++ b/test/gcfault.test @@ -10,7 +10,7 @@ #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing OOM error handling within the built-in -# group_concat() function. +# group_concat() and string_agg() functions. # set testdir [file dirname $argv0] @@ -40,7 +40,7 @@ foreach {enc} { } do_faultsim_test 1.$enc.2 -faults oom-t* -body { - execsql { SELECT group_concat(e, (SELECT s FROM s WHERE i=2)) FROM e } + execsql { SELECT string_agg(e, (SELECT s FROM s WHERE i=2)) FROM e } } do_faultsim_test 1.$enc.3 -faults oom-t* -prep { diff --git a/test/gencol1.test b/test/gencol1.test index f3fbb0dfba..ed7ea567d4 100644 --- a/test/gencol1.test +++ b/test/gencol1.test @@ -662,11 +662,8 @@ do_execsql_test gencol1-23.4 { # 2023-03-07 https://sqlite.org/forum/forumpost/b312e075b5 # -do_execsql_test gencol1-23.5 { +do_catchsql_test gencol1-23.5 { CREATE TABLE v0(c1 INT, c2 AS (RAISE(IGNORE))); -} -do_catchsql_test gencol1-23.6 { - SELECT * FROM v0; } {1 {RAISE() may only be used within a trigger-program}} finish_test diff --git a/test/indexA.test b/test/indexA.test new file mode 100644 index 0000000000..518d7e18ad --- /dev/null +++ b/test/indexA.test @@ -0,0 +1,350 @@ +# 2023 September 23 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix indexA + +do_execsql_test 1.0 { + CREATE TABLE t1(a TEXT, b, c); + CREATE INDEX i1 ON t1(b, c) WHERE a='abc'; + INSERT INTO t1 VALUES('abc', 1, 2); +} + +do_execsql_test 1.1 { + SELECT * FROM t1 WHERE a='abc' +} {abc 1 2} + +do_eqp_test 1.2 { + SELECT * FROM t1 WHERE a='abc' +} {USING COVERING INDEX i1} + +do_execsql_test 1.3 { + CREATE INDEX i2 ON t1(b, c) WHERE a=5; + INSERT INTO t1 VALUES(5, 4, 3); + + SELECT a, typeof(a), b, c FROM t1 WHERE a=5; +} {5 text 4 3} + +do_execsql_test 1.4 { + CREATE TABLE t2(x); + INSERT INTO t2 VALUES('v'); +} + +do_execsql_test 1.5 { + SELECT x, a, b, c FROM t2 LEFT JOIN t1 ON (a=5 AND b=x) +} {v {} {} {}} + +do_execsql_test 1.6 { + SELECT x, a, b, c FROM t2 RIGHT JOIN t1 ON (t1.a=5 AND t1.b=t2.x) +} {{} abc 1 2 {} 5 4 3} + +do_eqp_test 1.7 { + SELECT x, a, b, c FROM t2 RIGHT JOIN t1 ON (t1.a=5 AND t1.b=t2.x) +} {USING INDEX i2} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 2.0 { + CREATE TABLE x1(a TEXT, b, c); + INSERT INTO x1 VALUES('2', 'two', 'ii'); + INSERT INTO x1 VALUES('2.0', 'twopointoh', 'ii.0'); + + CREATE TABLE x2(a NUMERIC, b, c); + INSERT INTO x2 VALUES('2', 'two', 'ii'); + INSERT INTO x2 VALUES('2.0', 'twopointoh', 'ii.0'); + + CREATE TABLE x3(a REAL, b, c); + INSERT INTO x3 VALUES('2', 'two', 'ii'); + INSERT INTO x3 VALUES('2.0', 'twopointoh', 'ii.0'); +} + +foreach {tn idx} { + 0 { + } + 1 { + CREATE INDEX i1 ON x1(b, c) WHERE a=2; + CREATE INDEX i2 ON x2(b, c) WHERE a=2; + CREATE INDEX i3 ON x3(b, c) WHERE a=2; + } + 2 { + CREATE INDEX i1 ON x1(b, c) WHERE a=2.0; + CREATE INDEX i2 ON x2(b, c) WHERE a=2.0; + CREATE INDEX i3 ON x3(b, c) WHERE a=2.0; + } + 3 { + CREATE INDEX i1 ON x1(b, c) WHERE a='2.0'; + CREATE INDEX i2 ON x2(b, c) WHERE a='2.0'; + CREATE INDEX i3 ON x3(b, c) WHERE a='2.0'; + } + 4 { + CREATE INDEX i1 ON x1(b, c) WHERE a='2'; + CREATE INDEX i2 ON x2(b, c) WHERE a='2'; + CREATE INDEX i3 ON x3(b, c) WHERE a='2'; + } +} { + execsql { DROP INDEX IF EXISTS i1 } + execsql { DROP INDEX IF EXISTS i2 } + execsql { DROP INDEX IF EXISTS i3 } + + execsql $idx + do_execsql_test 2.1.$tn.1 { + SELECT *, typeof(a) FROM x1 WHERE a=2 + } {2 two ii text} + do_execsql_test 2.1.$tn.2 { + SELECT *, typeof(a) FROM x1 WHERE a=2.0 + } {2.0 twopointoh ii.0 text} + do_execsql_test 2.1.$tn.3 { + SELECT *, typeof(a) FROM x1 WHERE a='2' + } {2 two ii text} + do_execsql_test 2.1.$tn.4 { + SELECT *, typeof(a) FROM x1 WHERE a='2.0' + } {2.0 twopointoh ii.0 text} + + do_execsql_test 2.1.$tn.5 { + SELECT *, typeof(a) FROM x2 WHERE a=2 + } {2 two ii integer 2 twopointoh ii.0 integer} + do_execsql_test 2.1.$tn.6 { + SELECT *, typeof(a) FROM x2 WHERE a=2.0 + } {2 two ii integer 2 twopointoh ii.0 integer} + do_execsql_test 2.1.$tn.7 { + SELECT *, typeof(a) FROM x2 WHERE a='2' + } {2 two ii integer 2 twopointoh ii.0 integer} + do_execsql_test 2.1.$tn.8 { + SELECT *, typeof(a) FROM x2 WHERE a='2.0' + } {2 two ii integer 2 twopointoh ii.0 integer} + + do_execsql_test 2.1.$tn.9 { + SELECT *, typeof(a) FROM x3 WHERE a=2 + } {2.0 two ii real 2.0 twopointoh ii.0 real} + do_execsql_test 2.1.$tn.10 { + SELECT *, typeof(a) FROM x3 WHERE a=2.0 + } {2.0 two ii real 2.0 twopointoh ii.0 real} + do_execsql_test 2.1.$tn.11 { + SELECT *, typeof(a) FROM x3 WHERE a='2' + } {2.0 two ii real 2.0 twopointoh ii.0 real} + do_execsql_test 2.1.$tn.12 { + SELECT *, typeof(a) FROM x3 WHERE a='2.0' + } {2.0 two ii real 2.0 twopointoh ii.0 real} + +} + +reset_db +do_execsql_test 3.0 { + CREATE TABLE x1(a TEXT, d PRIMARY KEY, b, c) WITHOUT ROWID; + INSERT INTO x1 VALUES('2', 1, 'two', 'ii'); + INSERT INTO x1 VALUES('2.0', 2, 'twopointoh', 'ii.0'); + + CREATE TABLE x2(a NUMERIC, b, c, d PRIMARY KEY) WITHOUT ROWID; + INSERT INTO x2 VALUES('2', 'two', 'ii', 1); + INSERT INTO x2 VALUES('2.0', 'twopointoh', 'ii.0', 2); + + CREATE TABLE x3(d PRIMARY KEY, a REAL, b, c) WITHOUT ROWID; + INSERT INTO x3 VALUES(34, '2', 'two', 'ii'); + INSERT INTO x3 VALUES(35, '2.0', 'twopointoh', 'ii.0'); +} + +foreach {tn idx} { + 0 { + } + 1 { + CREATE INDEX i1 ON x1(b, c) WHERE a=2; + CREATE INDEX i2 ON x2(b, c) WHERE a=2; + CREATE INDEX i3 ON x3(b, c) WHERE a=2; + } + 2 { + CREATE INDEX i1 ON x1(b, c) WHERE a=2.0; + CREATE INDEX i2 ON x2(b, c) WHERE a=2.0; + CREATE INDEX i3 ON x3(b, c) WHERE a=2.0; + } + 3 { + CREATE INDEX i1 ON x1(b, c) WHERE a='2.0'; + CREATE INDEX i2 ON x2(b, c) WHERE a='2.0'; + CREATE INDEX i3 ON x3(b, c) WHERE a='2.0'; + } + 4 { + CREATE INDEX i1 ON x1(b, c) WHERE a='2'; + CREATE INDEX i2 ON x2(b, c) WHERE a='2'; + CREATE INDEX i3 ON x3(b, c) WHERE a='2'; + } +} { + execsql { DROP INDEX IF EXISTS i1 } + execsql { DROP INDEX IF EXISTS i2 } + execsql { DROP INDEX IF EXISTS i3 } + + execsql $idx + do_execsql_test 3.1.$tn.1 { + SELECT a, b, c, typeof(a) FROM x1 WHERE a=2 + } {2 two ii text} + do_execsql_test 3.1.$tn.2 { + SELECT a, b, c, typeof(a) FROM x1 WHERE a=2.0 + } {2.0 twopointoh ii.0 text} + do_execsql_test 3.1.$tn.3 { + SELECT a, b, c, typeof(a) FROM x1 WHERE a='2' + } {2 two ii text} + do_execsql_test 3.1.$tn.4 { + SELECT a, b, c, typeof(a) FROM x1 WHERE a='2.0' + } {2.0 twopointoh ii.0 text} + + do_execsql_test 3.1.$tn.5 { + SELECT a, b, c, typeof(a) FROM x2 WHERE a=2 + } {2 two ii integer 2 twopointoh ii.0 integer} + do_execsql_test 3.1.$tn.6 { + SELECT a, b, c, typeof(a) FROM x2 WHERE a=2.0 + } {2 two ii integer 2 twopointoh ii.0 integer} + do_execsql_test 3.1.$tn.7 { + SELECT a, b, c, typeof(a) FROM x2 WHERE a='2' + } {2 two ii integer 2 twopointoh ii.0 integer} + do_execsql_test 3.1.$tn.8 { + SELECT a, b, c, typeof(a) FROM x2 WHERE a='2.0' + } {2 two ii integer 2 twopointoh ii.0 integer} + + do_execsql_test 3.1.$tn.9 { + SELECT a, b, c, typeof(a) FROM x3 WHERE a=2 + } {2.0 two ii real 2.0 twopointoh ii.0 real} + do_execsql_test 3.1.$tn.10 { + SELECT a, b, c, typeof(a) FROM x3 WHERE a=2.0 + } {2.0 two ii real 2.0 twopointoh ii.0 real} + do_execsql_test 3.1.$tn.11 { + SELECT a, b, c, typeof(a) FROM x3 WHERE a='2' + } {2.0 two ii real 2.0 twopointoh ii.0 real} + do_execsql_test 3.1.$tn.12 { + SELECT a, b, c, typeof(a) FROM x3 WHERE a='2.0' + } {2.0 two ii real 2.0 twopointoh ii.0 real} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE TABLE t2(a INTEGER, b TEXT); + INSERT INTO t2 VALUES(1, 'two'); + INSERT INTO t2 VALUES(2, 'two'); + INSERT INTO t2 VALUES(3, 'two'); + INSERT INTO t2 VALUES(1, 'three'); + INSERT INTO t2 VALUES(2, 'three'); + INSERT INTO t2 VALUES(3, 'three'); + + CREATE INDEX t2a_two ON t2(a) WHERE b='two'; +} + +# explain_i { SELECT sum(a), b FROM t2 WHERE b='two' } +do_execsql_test 4.1.1 { + SELECT sum(a), b FROM t2 WHERE b='two' +} {6 two} +do_eqp_test 4.1.2 { + SELECT sum(a), b FROM t2 WHERE b='two' +} {USING COVERING INDEX t2a_two} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE TABLE t1(a INTEGER PRIMQRY KEY, b, c); +} +do_catchsql_test 5.1 { + CREATE INDEX ex1 ON t1(c) WHERE b IS 'abc' COLLATE g; +} {1 {no such collation sequence: g}} + +proc xyz {lhs rhs} { + return [string compare $lhs $rhs] +} +db collate xyz xyz +do_execsql_test 5.2 { + CREATE INDEX ex1 ON t1(c) WHERE b IS 'abc' COLLATE xyz; +} +db close +sqlite3 db test.db +do_execsql_test 5.3 { + SELECT * FROM t1 +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE TABLE t2(x INTEGER PRIMARY KEY, y INTEGER, z INTEGER); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 1, 2); + INSERT INTO t2 VALUES(1, 5, 1); + INSERT INTO t2 VALUES(2, 5, 2); + + CREATE INDEX t2z ON t2(z) WHERE y=5; +} + +do_execsql_test 6.1 { + ANALYZE; + UPDATE sqlite_stat1 SET stat = '50 1' WHERE idx='t2z'; + UPDATE sqlite_stat1 SET stat = '50' WHERE tbl='t2' AND idx IS NULL; + UPDATE sqlite_stat1 SET stat = '5000' WHERE tbl='t1' AND idx IS NULL; + ANALYZE sqlite_schema; +} + +do_execsql_test 6.2 { + SELECT * FROM t1, t2 WHERE b=1 AND z=c AND y=5; +} { + 1 1 1 1 5 1 + 2 1 2 2 5 2 +} + +do_eqp_test 6.3 { + SELECT * FROM t1, t2 WHERE b=1 AND z=c AND y=5; +} {BLOOM FILTER ON t2} + +do_execsql_test 6.4 { + SELECT * FROM t1 LEFT JOIN t2 ON (y=5) WHERE b=1 AND z IS c; +} { + 1 1 1 1 5 1 + 2 1 2 2 5 2 +} + +do_eqp_test 6.5 { + SELECT * FROM t1 LEFT JOIN t2 ON (y=5) WHERE b=1 AND z IS c; +} {BLOOM FILTER ON t2} + +do_execsql_test 6.6 { + CREATE INDEX t2yz ON t2(y, z) WHERE y=5; +} + +do_execsql_test 6.7 { + SELECT * FROM t1 LEFT JOIN t2 ON (y=5) WHERE b=1 AND z IS c; +} { + 1 1 1 1 5 1 + 2 1 2 2 5 2 +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(i INTEGER PRIMARY KEY, b TEXT, c TEXT); + CREATE INDEX i1 ON t1(c) WHERE b='abc' AND i=5; + INSERT INTO t1 VALUES(5, 'abc', 'xyz'); + SELECT * FROM t1 INDEXED BY i1 WHERE b='abc' AND i=5 ORDER BY c; +} {5 abc xyz} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 8.0 { + CREATE TABLE t1(a, b, c); + CREATE INDEX ex2 ON t1(a, 4); + CREATE INDEX ex1 ON t1(a) WHERE 4=b; + INSERT INTO t1 VALUES(1, 4, 1); + INSERT INTO t1 VALUES(1, 5, 1); + INSERT INTO t1 VALUES(2, 4, 2); +} +do_execsql_test 8.1 { + SELECT * FROM t1 WHERE b=4; +} { + 1 4 1 2 4 2 +} + +finish_test diff --git a/test/joinH.test b/test/joinH.test index 027f0a3999..0fed7f2aa0 100644 --- a/test/joinH.test +++ b/test/joinH.test @@ -252,4 +252,3 @@ do_catchsql_test 9.11 { finish_test - diff --git a/test/json101.test b/test/json101.test index 4da1d132cc..c62991bbbf 100644 --- a/test/json101.test +++ b/test/json101.test @@ -119,6 +119,9 @@ do_execsql_test json101-4.7 { do_execsql_test json101-4.8 { SELECT x FROM j1 WHERE json_insert(x)<>x; } {} +do_execsql_test json101-4.9 { + SELECT json_insert('{"a":1}','$.b',CAST(x'0000' AS text)); +} {{{"a":1,"b":"\u0000\u0000"}}} # json_extract(JSON,'$') will return objects and arrays without change. # @@ -1013,7 +1016,43 @@ do_execsql_test json101-21.27 { SELECT json_group_object(x,y) FROM c; } {{{"a":1,"b":2.0,"c":null,:"three","e":"four"}}} +# 2023-10-09 https://sqlite.org/forum/forumpost/b25edc1d46 +# UAF due to JSON cache overflow +# +do_execsql_test json101-22.1 { + SELECT json_set( + '{}', + '$.a', json('1'), + '$.a', json('2'), + '$.b', json('3'), + '$.b', json('4'), + '$.c', json('5'), + '$.c', json('6') + ); +} {{{"a":2,"b":4,"c":6}}} +do_execsql_test json101-22.2 { + SELECT json_replace( + '{"a":7,"b":8,"c":9}', + '$.a', json('1'), + '$.a', json('2'), + '$.b', json('3'), + '$.b', json('4'), + '$.c', json('5'), + '$.c', json('6') + ); +} {{{"a":2,"b":4,"c":6}}} +# 2023-10-17 https://sqlite.org/forum/forumpost/fc0e3f1e2a +# Incorrect accesss to '$[0]' in parsed + edited JSON. +# +do_execsql_test json101-23.1 { + SELECT j, j->>0, j->>1 + FROM (SELECT json_set(json_set('[]','$[#]',0), '$[#]',1) AS j); +} {{[0,1]} 0 1} +do_execsql_test json101-23.2 { + SELECT j, j->>0, j->>1 + FROM (SELECT json_set('[]','$[#]',0,'$[#]',1) AS j); +} {{[0,1]} 0 1} diff --git a/test/memdb2.test b/test/memdb2.test index 286bfc3f84..7c2144991f 100644 --- a/test/memdb2.test +++ b/test/memdb2.test @@ -74,4 +74,3 @@ foreach {tn fname} { } finish_test - diff --git a/test/memjournal2.test b/test/memjournal2.test index ec5ba56da3..d08bcb5a6a 100644 --- a/test/memjournal2.test +++ b/test/memjournal2.test @@ -59,5 +59,3 @@ for {set jj 200} {$jj <= 300} {incr jj} { finish_test - - diff --git a/test/pendingrace.test b/test/pendingrace.test index f0e1a18ffa..ef42578f21 100644 --- a/test/pendingrace.test +++ b/test/pendingrace.test @@ -121,6 +121,3 @@ tvfs delete tvfs2 delete finish_test - - - diff --git a/test/quickcheck.test b/test/quickcheck.test index 94016e845f..18c42a13d0 100644 --- a/test/quickcheck.test +++ b/test/quickcheck.test @@ -31,4 +31,3 @@ do_execsql_test 1.1 { } finish_test - diff --git a/test/rowvalue9.test b/test/rowvalue9.test index aee5e7ea4f..baa13f4f94 100644 --- a/test/rowvalue9.test +++ b/test/rowvalue9.test @@ -350,5 +350,3 @@ do_eqp_test 9.5e { finish_test - - diff --git a/test/rowvalueA.test b/test/rowvalueA.test index dc5a7a014b..8760c2c396 100644 --- a/test/rowvalueA.test +++ b/test/rowvalueA.test @@ -74,4 +74,3 @@ do_catchsql_test 2.3 { } {1 {row value misused}} finish_test - diff --git a/test/scanstatus2.test b/test/scanstatus2.test index cbffee0185..e4b510d20f 100644 --- a/test/scanstatus2.test +++ b/test/scanstatus2.test @@ -145,8 +145,8 @@ do_graph_test 1.4 { QUERY (nCycle=nnn) --MATERIALIZE v2 (nCycle=nnn) ----SCAN t2 (nCycle=nnn) ---SCAN v2 (nCycle=nnn) --SCAN t1 (nCycle=nnn) +--SCAN v2 (nCycle=nnn) --USE TEMP B-TREE FOR ORDER BY (nCycle=nnn) } @@ -332,5 +332,3 @@ QUERY (nCycle=nnn) #puts_debug_info { SELECT (a % 2), group_concat(b) FROM t1 GROUP BY 1 } finish_test - - diff --git a/test/select3.test b/test/select3.test index 4c9d71b4f5..4bbd70cc75 100644 --- a/test/select3.test +++ b/test/select3.test @@ -434,4 +434,3 @@ do_execsql_test 12.8 { } finish_test - diff --git a/test/sessionfuzz.c b/test/sessionfuzz.c index f2e4cd5a68..093c2b043d 100644 --- a/test/sessionfuzz.c +++ b/test/sessionfuzz.c @@ -66,14 +66,6 @@ #define SQLITE_ENABLE_DESERIALIZE 1 #include "sqlite3.c" -/* Create a test database. This will be an in-memory database */ -static const char zInitSql[] = - "CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d);\n" - "CREATE TABLE t2(e TEXT PRIMARY KEY NOT NULL,f,g);\n" - "CREATE TABLE t3(w REAL PRIMARY KEY NOT NULL,x,y);\n" - "CREATE TABLE t4(z PRIMARY KEY) WITHOUT ROWID;\n" -; - /* Code to populate the database */ static const char zFillSql[] = "INSERT INTO t1(a,b,c,d) VALUES\n" diff --git a/test/statfault.test b/test/statfault.test index b5980d417d..19e0a67874 100644 --- a/test/statfault.test +++ b/test/statfault.test @@ -52,4 +52,3 @@ do_faultsim_test 2 -faults * -prep { } finish_test - diff --git a/test/table.test b/test/table.test index 7be6b37695..b961207f8b 100644 --- a/test/table.test +++ b/test/table.test @@ -784,13 +784,13 @@ do_catchsql_test table-16.5 { } {1 {unknown function: count()}} do_catchsql_test table-16.6 { DROP TABLE t16; - CREATE TABLE t16(x DEFAULT(group_concat('x',','))); + CREATE TABLE t16(x DEFAULT(string_agg('x',','))); INSERT INTO t16(rowid) VALUES(123); SELECT rowid, x FROM t16; -} {1 {unknown function: group_concat()}} +} {1 {unknown function: string_agg()}} do_catchsql_test table-16.7 { INSERT INTO t16 DEFAULT VALUES; -} {1 {unknown function: group_concat()}} +} {1 {unknown function: string_agg()}} # Ticket [https://www.sqlite.org/src/info/094d39a4c95ee4abbc417f04214617675ba15c63] # describes a assertion fault that occurs on a CREATE TABLE .. AS SELECT statement. diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 9946d88649..1f1862ffdd 100644 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -963,13 +963,19 @@ proc one_line_report {} { foreach j [lsort [array names t]] { foreach k {done failed running} { incr v($k,$j) 0 } set fin [expr $v(done,$j) + $v(failed,$j)] - lappend text "$j ($fin/$t($j)) f=$v(failed,$j) r=$v(running,$j)" + lappend text "${j}($fin/$t($j))" + if {$v(failed,$j)>0} { + lappend text "f$v(failed,$j)" + } + if {$v(running,$j)>0} { + lappend text "r$v(running,$j)" + } } if {[info exists TRG(reportlength)]} { puts -nonewline "[string repeat " " $TRG(reportlength)]\r" } - set report "${tm}s: [join $text { }]" + set report "${tm} [join $text { }]" set TRG(reportlength) [string length $report] if {[string length $report]<100} { puts -nonewline "$report\r" diff --git a/test/thread3.test b/test/thread3.test index 25699b7655..79a75bdbb7 100644 --- a/test/thread3.test +++ b/test/thread3.test @@ -75,4 +75,3 @@ do_execsql_test "1.Total BUSY errors: $nTotalBusy .2" { } $nAttempt finish_test - diff --git a/test/tkt-cbd054fa6b.test b/test/tkt-cbd054fa6b.test index 86248ca21d..435d807873 100644 --- a/test/tkt-cbd054fa6b.test +++ b/test/tkt-cbd054fa6b.test @@ -65,7 +65,7 @@ do_test tkt-cbd05-1.2 { } {} do_test tkt-cbd05-1.3 { execsql { - SELECT tbl,idx,group_concat(s(sample),' ') + SELECT tbl,idx,string_agg(s(sample),' ') FROM vvv WHERE idx = 't1_x' GROUP BY tbl,idx diff --git a/test/trigger2.test b/test/trigger2.test index 6e007e969a..70d59f3a0b 100644 --- a/test/trigger2.test +++ b/test/trigger2.test @@ -790,4 +790,3 @@ do_catchsql_test 11.2 { finish_test - diff --git a/test/unhex.test b/test/unhex.test index f41e906a8f..af2cfae390 100644 --- a/test/unhex.test +++ b/test/unhex.test @@ -55,6 +55,8 @@ do_catchsql_test 3.1 { #-------------------------------------------------------------------------- # Test the 2-argument version. # +# Zap global x array set in some previous test. +if {[array exists x]} {array unset x} foreach {tn hex} { 1 "FFFF ABCD" 2 "FFFF ABCD" @@ -98,5 +100,3 @@ do_execsql_test 6.4.3 { SELECT typeof(unhex('1234', NULL)) } {null} finish_test - - diff --git a/test/vacuum-into.test b/test/vacuum-into.test index 98692a108a..698d65f540 100644 --- a/test/vacuum-into.test +++ b/test/vacuum-into.test @@ -185,6 +185,3 @@ tvfs delete finish_test - - - diff --git a/test/vt02.c b/test/vt02.c index ddad136fba..350a0400e9 100644 --- a/test/vt02.c +++ b/test/vt02.c @@ -983,7 +983,9 @@ const sqlite3_module vt02Module = { /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0, - /* xRollbackTo */ 0 + /* xRollbackTo */ 0, + /* xShadowName */ 0, + /* xIntegrity */ 0 }; static void vt02CoreInit(sqlite3 *db){ diff --git a/test/walseh1.test b/test/walseh1.test index c3a655f534..225b69f742 100644 --- a/test/walseh1.test +++ b/test/walseh1.test @@ -146,5 +146,3 @@ do_faultsim_test 6 -faults seh -prep { catch { db close } finish_test - - diff --git a/test/window1.test b/test/window1.test index 37a5183f90..c9bbae3ee0 100644 --- a/test/window1.test +++ b/test/window1.test @@ -158,7 +158,7 @@ do_execsql_test 4.9 { do_execsql_test 4.10.1 { SELECT a, count() OVER (ORDER BY a DESC), - group_concat(a, '.') OVER (ORDER BY a DESC) + string_agg(a, '.') OVER (ORDER BY a DESC) FROM t2 ORDER BY a DESC } { 6 1 6 @@ -825,7 +825,7 @@ foreach {tn sql error} { } do_execsql_test 18.3.1 { - SELECT group_concat(c, '.') OVER (PARTITION BY b ORDER BY c) + SELECT string_agg(c, '.') OVER (PARTITION BY b ORDER BY c) FROM t1 } {four four.six four.six.two five five.one five.one.three} @@ -836,7 +836,7 @@ do_execsql_test 18.3.2 { } {four four.six four.six.two five five.one five.one.three} do_execsql_test 18.3.3 { - SELECT group_concat(c, '.') OVER win2 + SELECT string_agg(c, '.') OVER win2 FROM t1 WINDOW win1 AS (PARTITION BY b), win2 AS (win1 ORDER BY c) @@ -850,7 +850,7 @@ do_execsql_test 18.3.4 { } {four four.six four.six.two five five.one five.one.three} do_execsql_test 18.3.5 { - SELECT group_concat(c, '.') OVER win5 + SELECT string_agg(c, '.') OVER win5 FROM t1 WINDOW win1 AS (PARTITION BY b), win2 AS (win1), @@ -1127,7 +1127,7 @@ do_execsql_test 28.1.1 { } do_execsql_test 28.1.2 { - SELECT group_concat(b,'') OVER w1 FROM t1 + SELECT string_agg(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY a RANGE BETWEEN 3 PRECEDING AND 1 PRECEDING) } { {} {} diff --git a/test/window3.test b/test/window3.test index 4f759abb7e..1893b539d3 100644 --- a/test/window3.test +++ b/test/window3.test @@ -1181,7 +1181,7 @@ do_execsql_test 1.1.13.6 { {} {} {} {} {} {} {} {} {} {} {}} do_execsql_test 1.1.14.1 { - SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 + SELECT string_agg(CAST(b AS TEXT), '.') OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 } {89 89.81 89.81.96 89.81.96.59 89.81.96.59.38 89.81.96.59.38.68 89.81.96.59.38.68.39 89.81.96.59.38.68.39.62 89.81.96.59.38.68.39.62.91 89.81.96.59.38.68.39.62.91.46 89.81.96.59.38.68.39.62.91.46.6 @@ -1471,7 +1471,7 @@ do_execsql_test 1.1.14.2 { 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} do_execsql_test 1.1.14.3 { - SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 + SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 } {1 1.1 1.1.2 1.1.2.2 1.1.2.2.3 1.1.2.2.3.3 1.1.2.2.3.3.4 1.1.2.2.3.3.4.5 1.1.2.2.3.3.4.5.6 1.1.2.2.3.3.4.5.6.7 1.1.2.2.3.3.4.5.6.7.7 1.1.2.2.3.3.4.5.6.7.7.7 1.1.2.2.3.3.4.5.6.7.7.7.8 @@ -1758,7 +1758,7 @@ do_execsql_test 1.1.14.4 { 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99} do_execsql_test 1.1.14.5 { - SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 + SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 } {90 90.40 90.40.30 90.40.30.80 90.40.30.80.20 90.40.30.80.20.90 90.40.30.80.20.90.60 90.40.30.80.20.90.60.70 90.40.30.80.20.90.60.70.80 90.40.30.80.20.90.60.70.80.90 90.40.30.80.20.90.60.70.80.90.30 @@ -1960,7 +1960,7 @@ do_execsql_test 1.1.14.6 { 83 27 17 7} do_execsql_test 1.1.14.7 { - SELECT group_concat(CAST(b AS TEXT), '.') OVER (win1 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + SELECT string_agg(CAST(b AS TEXT), '.') OVER (win1 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 WINDOW win1 AS (PARTITION BY b%2,a) ORDER BY 1 diff --git a/tool/cktclsh.sh b/tool/cktclsh.sh new file mode 100644 index 0000000000..1928a40998 --- /dev/null +++ b/tool/cktclsh.sh @@ -0,0 +1,11 @@ +# Fail with an error if the TCLSH named in $2 is not tclsh version $1 or later. +# +echo "set vers $1" >cktclsh$1.tcl +echo 'if {$tcl_version<$vers} {exit 1}' >>cktclsh$1.tcl +if ! $2 cktclsh$1.tcl +then + echo "ERROR: This makefile target requires tclsh $1 or later." + rm cktclsh$1.tcl + exit 1 +fi +rm cktclsh$1.tcl diff --git a/tool/fuzzershell.c b/tool/fuzzershell.c index 9a27103597..7a7aef0290 100644 --- a/tool/fuzzershell.c +++ b/tool/fuzzershell.c @@ -680,6 +680,11 @@ static sqlite3_module seriesModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* END the generate_series(START,END,STEP) implementation *********************************************************************************/ diff --git a/tool/mkautoconfamal.sh b/tool/mkautoconfamal.sh index b7483189da..35dbfb41e0 100644 --- a/tool/mkautoconfamal.sh +++ b/tool/mkautoconfamal.sh @@ -28,7 +28,7 @@ DATETIME=`grep '^D' $TOP/manifest | sed -e 's/[^0-9]//g' -e 's/\(............\). # Verify that the version number in the TEA autoconf file is correct. # Fail with an error if not. # -if grep $VERSION autoconf/tea/configure.ac +if grep $VERSION $TOP/autoconf/tea/configure.ac then echo "TEA version number ok" else echo "TEA version number mismatch. Should be $VERSION"; exit 1 fi diff --git a/tool/mkctimec.tcl b/tool/mkctimec.tcl index 23726a722f..098bf16e3b 100755 --- a/tool/mkctimec.tcl +++ b/tool/mkctimec.tcl @@ -239,6 +239,7 @@ set boolean_defnil_options { SQLITE_OMIT_REINDEX SQLITE_OMIT_SCHEMA_PRAGMAS SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + SQLITE_OMIT_SEH SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_SHUTDOWN_DIRECTORIES SQLITE_OMIT_SUBQUERY diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index d0c5e65e38..8fe72b99b1 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -581,6 +581,7 @@ set inuse_pgcnt [expr wide([mem eval $sql])] set inuse_percent [percent $inuse_pgcnt $file_pgcnt] set free_pgcnt [expr {$file_pgcnt-$inuse_pgcnt-$av_pgcnt}] +if {$file_bytes>1073741824 && $free_pgcnt>0} {incr free_pgcnt -1} set free_percent [percent $free_pgcnt $file_pgcnt] set free_pgcnt2 [db one {PRAGMA freelist_count}] set free_percent2 [percent $free_pgcnt2 $file_pgcnt] diff --git a/tool/srctree-check.tcl b/tool/srctree-check.tcl new file mode 100644 index 0000000000..234e70fae9 --- /dev/null +++ b/tool/srctree-check.tcl @@ -0,0 +1,79 @@ +#!/usr/bin/tclsh +# +# Run this script from the top of the source tree in order to confirm that +# various aspects of the source tree are up-to-date. Items checked include: +# +# * Makefile.msc and autoconf/Makefile.msc agree +# * src/ctime.tcl is consistent with tool/mkctimec.tcl +# * VERSION agrees with autoconf/tea/configure.ac +# * src/pragma.h agrees with tool/mkpragmatab.tcl +# +# Other tests might be added later. +# +# Error messages are printed and the process exists non-zero if problems +# are found. If everything is ok, no output is generated and the process +# exits with 0. +# + +# Read an entire file. +# +proc readfile {filename} { + set fd [open $filename rb] + set txt [read $fd] + close $fd + return $txt +} + +# Find the root of the tree. +# +set ROOT [file dir [file dir [file normalize $argv0]]] +cd $ROOT + +# Name of the TCL interpreter +# +set TCLSH [info nameofexe] + +######################### autoconf/tea/configure.ac ########################### + +set confac [readfile $ROOT/autoconf/tea/configure.ac] +set vers [readfile $ROOT/VERSION] +set pattern {AC_INIT([sqlite],[} +append pattern [string trim $vers] +append pattern {])} +if {[string first $pattern $confac]<=0} { + puts "ERROR: ./autoconf/tea/configure.ac does not agree with ./VERSION" + exit 1 +} + +######################### autoconf/Makefile.msc ############################### + +set f1 [readfile $ROOT/autoconf/Makefile.msc] +exec mv $ROOT/autoconf/Makefile.msc $ROOT/autoconf/Makefile.msc.tmp +exec $TCLSH $ROOT/tool/mkmsvcmin.tcl +set f2 [readfile $ROOT/autoconf/Makefile.msc] +exec mv $ROOT/autoconf/Makefile.msc.tmp $ROOT/autoconf/Makefile.msc +if {$f1 != $f2} { + puts "ERROR: ./autoconf/Makefile.msc does not agree with ./Makefile.msc" +} + +######################### src/pragma.h ######################################## + +set f1 [readfile $ROOT/src/pragma.h] +exec mv $ROOT/src/pragma.h $ROOT/src/pragma.h.tmp +exec $TCLSH $ROOT/tool/mkpragmatab.tcl +set f2 [readfile $ROOT/src/pragma.h] +exec mv $ROOT/src/pragma.h.tmp $ROOT/src/pragma.h +if {$f1 != $f2} { + puts "ERROR: ./src/pragma.h does not agree with ./tool/mkpragmatab.tcl" +} + +######################### src/ctime.c ######################################## + +set f1 [readfile $ROOT/src/ctime.c] +exec mv $ROOT/src/ctime.c $ROOT/src/ctime.c.tmp +exec $TCLSH $ROOT/tool/mkctimec.tcl +set f2 [readfile $ROOT/src/ctime.c] +exec mv $ROOT/src/ctime.c.tmp $ROOT/src/ctime.c +if {$f1 != $f2} { + puts "ERROR: ./src/ctime.c does not agree with ./tool/mkctimec.tcl" +}