Merge fixes and enhancements from trunk.
FossilOrigin-Name: 589186c083ff3af8d5a6d5ad34e1cefea57806ebf3831ea3bf5a48ef1e173140
This commit is contained in:
commit
c840b428fc
@ -350,7 +350,8 @@ SRC += \
|
||||
$(TOP)/ext/icu/icu.c
|
||||
SRC += \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.c
|
||||
$(TOP)/ext/rtree/rtree.c \
|
||||
$(TOP)/ext/rtree/geopoly.c
|
||||
SRC += \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/session/sqlite3session.h
|
||||
@ -552,7 +553,8 @@ EXTHDR += \
|
||||
$(TOP)/ext/fts3/fts3_hash.h \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/rtree.h
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/geopoly.c
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
EXTHDR += \
|
||||
|
@ -338,7 +338,7 @@ SQLITE_TCL_DEP =
|
||||
!IFNDEF OPT_FEATURE_FLAGS
|
||||
!IF $(MINIMAL_AMALGAMATION)==0
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1
|
||||
!ENDIF
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
!ENDIF
|
||||
@ -1413,6 +1413,7 @@ SRC09 = \
|
||||
$(TOP)\ext\fts3\fts3_tokenizer.h \
|
||||
$(TOP)\ext\icu\sqliteicu.h \
|
||||
$(TOP)\ext\rtree\rtree.h \
|
||||
$(TOP)\ext\rtree\geopoly.c \
|
||||
$(TOP)\ext\rbu\sqlite3rbu.h \
|
||||
$(TOP)\ext\session\sqlite3session.h
|
||||
|
||||
@ -1587,7 +1588,8 @@ EXTHDR = $(EXTHDR) \
|
||||
$(TOP)\ext\fts3\fts3_hash.h \
|
||||
$(TOP)\ext\fts3\fts3_tokenizer.h
|
||||
EXTHDR = $(EXTHDR) \
|
||||
$(TOP)\ext\rtree\rtree.h
|
||||
$(TOP)\ext\rtree\rtree.h \
|
||||
$(TOP)\ext\rtree\geopoly.c
|
||||
EXTHDR = $(EXTHDR) \
|
||||
$(TOP)\ext\icu\sqliteicu.h
|
||||
EXTHDR = $(EXTHDR) \
|
||||
|
@ -1,7 +1,8 @@
|
||||
<h1 align="center">SQLite Source Repository</h1>
|
||||
|
||||
This repository contains the complete source code for the SQLite database
|
||||
engine. Some test scripts are also included. However, many other test scripts
|
||||
This repository contains the complete source code for the
|
||||
[SQLite database engine](https://sqlite.org/). Some test scripts
|
||||
are also included. However, many other test scripts
|
||||
and most of the documentation are managed separately.
|
||||
|
||||
SQLite [does not use Git](https://sqlite.org/whynotgit.html).
|
||||
|
44
configure
vendored
44
configure
vendored
@ -911,6 +911,7 @@ enable_fts4
|
||||
enable_fts5
|
||||
enable_json1
|
||||
enable_update_limit
|
||||
enable_geopoly
|
||||
enable_rtree
|
||||
enable_session
|
||||
enable_gcov
|
||||
@ -1563,6 +1564,7 @@ Optional Features:
|
||||
--enable-fts5 Enable the FTS5 extension
|
||||
--enable-json1 Enable the JSON1 extension
|
||||
--enable-update-limit Enable the UPDATE/DELETE LIMIT clause
|
||||
--enable-geopoly Enable the GEOPOLY extension
|
||||
--enable-rtree Enable the RTREE extension
|
||||
--enable-session Enable the SESSION extension
|
||||
--enable-gcov Enable coverage testing using gcov
|
||||
@ -3932,13 +3934,13 @@ if ${lt_cv_nm_interface+:} false; then :
|
||||
else
|
||||
lt_cv_nm_interface="BSD nm"
|
||||
echo "int some_variable = 0;" > conftest.$ac_ext
|
||||
(eval echo "\"\$as_me:3935: $ac_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:3937: $ac_compile\"" >&5)
|
||||
(eval "$ac_compile" 2>conftest.err)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3938: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval echo "\"\$as_me:3940: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3941: output\"" >&5)
|
||||
(eval echo "\"\$as_me:3943: output\"" >&5)
|
||||
cat conftest.out >&5
|
||||
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
|
||||
lt_cv_nm_interface="MS dumpbin"
|
||||
@ -5144,7 +5146,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 5147 "configure"' > conftest.$ac_ext
|
||||
echo '#line 5149 "configure"' > conftest.$ac_ext
|
||||
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@ -6669,11 +6671,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:6672: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6674: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:6676: \$? = $ac_status" >&5
|
||||
echo "$as_me:6678: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -7008,11 +7010,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7011: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7013: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:7015: \$? = $ac_status" >&5
|
||||
echo "$as_me:7017: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -7113,11 +7115,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7116: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7118: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7120: \$? = $ac_status" >&5
|
||||
echo "$as_me:7122: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -7168,11 +7170,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7171: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7173: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7175: \$? = $ac_status" >&5
|
||||
echo "$as_me:7177: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -9548,7 +9550,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9551 "configure"
|
||||
#line 9553 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -9644,7 +9646,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9647 "configure"
|
||||
#line 9649 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -11610,6 +11612,20 @@ if test "${enable_udlimit}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable GEOPOLY
|
||||
# Check whether --enable-geopoly was given.
|
||||
if test "${enable_geopoly+set}" = set; then :
|
||||
enableval=$enable_geopoly; enable_geopoly=yes
|
||||
else
|
||||
enable_geopoly=no
|
||||
fi
|
||||
|
||||
if test "${enable_geopoly}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
|
||||
enable_rtree=yes
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable RTREE
|
||||
# Check whether --enable-rtree was given.
|
||||
|
10
configure.ac
10
configure.ac
@ -649,6 +649,16 @@ if test "${enable_udlimit}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable GEOPOLY
|
||||
AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly],
|
||||
[Enable the GEOPOLY extension]),
|
||||
[enable_geopoly=yes],[enable_geopoly=no])
|
||||
if test "${enable_geopoly}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
|
||||
enable_rtree=yes
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable RTREE
|
||||
AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
|
||||
|
@ -365,7 +365,7 @@ static int completionFilter(
|
||||
pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
|
||||
if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
|
||||
}
|
||||
iArg++;
|
||||
iArg = 1;
|
||||
}
|
||||
if( idxNum & 2 ){
|
||||
pCur->nLine = sqlite3_value_bytes(argv[iArg]);
|
||||
@ -373,7 +373,6 @@ static int completionFilter(
|
||||
pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
|
||||
if( pCur->zLine==0 ) return SQLITE_NOMEM;
|
||||
}
|
||||
iArg++;
|
||||
}
|
||||
if( pCur->zLine!=0 && pCur->zPrefix==0 ){
|
||||
int i = pCur->nLine;
|
||||
|
@ -172,6 +172,7 @@ struct JsonParse {
|
||||
u8 nErr; /* Number of errors seen */
|
||||
u16 iDepth; /* Nesting depth */
|
||||
int nJson; /* Length of the zJson string in bytes */
|
||||
u32 iHold; /* Replace cache line with the lowest iHold value */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -976,7 +977,8 @@ static int jsonParseFindParents(JsonParse *pParse){
|
||||
/*
|
||||
** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
|
||||
*/
|
||||
#define JSON_CACHE_ID (-429938)
|
||||
#define JSON_CACHE_ID (-429938) /* First cache entry */
|
||||
#define JSON_CACHE_SZ 4 /* Max number of cache entries */
|
||||
|
||||
/*
|
||||
** Obtain a complete parse of the JSON found in the first argument
|
||||
@ -988,16 +990,42 @@ static int jsonParseFindParents(JsonParse *pParse){
|
||||
*/
|
||||
static JsonParse *jsonParseCached(
|
||||
sqlite3_context *pCtx,
|
||||
sqlite3_value **argv
|
||||
sqlite3_value **argv,
|
||||
sqlite3_context *pErrCtx
|
||||
){
|
||||
const char *zJson = (const char*)sqlite3_value_text(argv[0]);
|
||||
int nJson = sqlite3_value_bytes(argv[0]);
|
||||
JsonParse *p;
|
||||
JsonParse *pMatch = 0;
|
||||
int iKey;
|
||||
int iMinKey = 0;
|
||||
u32 iMinHold = 0xffffffff;
|
||||
u32 iMaxHold = 0;
|
||||
if( zJson==0 ) return 0;
|
||||
p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
|
||||
if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){
|
||||
p->nErr = 0;
|
||||
return p; /* The cached entry matches, so return it */
|
||||
for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
|
||||
p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
|
||||
if( p==0 ){
|
||||
iMinKey = iKey;
|
||||
break;
|
||||
}
|
||||
if( pMatch==0
|
||||
&& p->nJson==nJson
|
||||
&& memcmp(p->zJson,zJson,nJson)==0
|
||||
){
|
||||
p->nErr = 0;
|
||||
pMatch = p;
|
||||
}else if( p->iHold<iMinHold ){
|
||||
iMinHold = p->iHold;
|
||||
iMinKey = iKey;
|
||||
}
|
||||
if( p->iHold>iMaxHold ){
|
||||
iMaxHold = p->iHold;
|
||||
}
|
||||
}
|
||||
if( pMatch ){
|
||||
pMatch->nErr = 0;
|
||||
pMatch->iHold = iMaxHold+1;
|
||||
return pMatch;
|
||||
}
|
||||
p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
|
||||
if( p==0 ){
|
||||
@ -1007,13 +1035,15 @@ static JsonParse *jsonParseCached(
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->zJson = (char*)&p[1];
|
||||
memcpy((char*)p->zJson, zJson, nJson+1);
|
||||
if( jsonParse(p, pCtx, p->zJson) ){
|
||||
if( jsonParse(p, pErrCtx, p->zJson) ){
|
||||
sqlite3_free(p);
|
||||
return 0;
|
||||
}
|
||||
p->nJson = nJson;
|
||||
sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree);
|
||||
return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
|
||||
p->iHold = iMaxHold+1;
|
||||
sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
|
||||
(void(*)(void*))jsonParseFree);
|
||||
return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1386,7 +1416,7 @@ static void jsonArrayLengthFunc(
|
||||
u32 i;
|
||||
JsonNode *pNode;
|
||||
|
||||
p = jsonParseCached(ctx, argv);
|
||||
p = jsonParseCached(ctx, argv, ctx);
|
||||
if( p==0 ) return;
|
||||
assert( p->nNode );
|
||||
if( argc==2 ){
|
||||
@ -1427,7 +1457,7 @@ static void jsonExtractFunc(
|
||||
int i;
|
||||
|
||||
if( argc<2 ) return;
|
||||
p = jsonParseCached(ctx, argv);
|
||||
p = jsonParseCached(ctx, argv, ctx);
|
||||
if( p==0 ) return;
|
||||
jsonInit(&jx, ctx);
|
||||
jsonAppendChar(&jx, '[');
|
||||
@ -1734,22 +1764,21 @@ static void jsonTypeFunc(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
JsonParse x; /* The parse */
|
||||
JsonParse *p; /* The parse */
|
||||
const char *zPath;
|
||||
JsonNode *pNode;
|
||||
|
||||
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
|
||||
assert( x.nNode );
|
||||
p = jsonParseCached(ctx, argv, ctx);
|
||||
if( p==0 ) return;
|
||||
if( argc==2 ){
|
||||
zPath = (const char*)sqlite3_value_text(argv[1]);
|
||||
pNode = jsonLookup(&x, zPath, 0, ctx);
|
||||
pNode = jsonLookup(p, zPath, 0, ctx);
|
||||
}else{
|
||||
pNode = x.aNode;
|
||||
pNode = p->aNode;
|
||||
}
|
||||
if( pNode ){
|
||||
sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
|
||||
}
|
||||
jsonParseReset(&x);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1763,15 +1792,10 @@ static void jsonValidFunc(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
JsonParse x; /* The parse */
|
||||
int rc = 0;
|
||||
|
||||
JsonParse *p; /* The parse */
|
||||
UNUSED_PARAM(argc);
|
||||
if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
|
||||
rc = 1;
|
||||
}
|
||||
jsonParseReset(&x);
|
||||
sqlite3_result_int(ctx, rc);
|
||||
p = jsonParseCached(ctx, argv, 0);
|
||||
sqlite3_result_int(ctx, p!=0);
|
||||
}
|
||||
|
||||
|
||||
|
1659
ext/rtree/geopoly.c
Normal file
1659
ext/rtree/geopoly.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -127,6 +127,7 @@ struct Rtree {
|
||||
u8 nBytesPerCell; /* Bytes consumed per cell */
|
||||
u8 inWrTrans; /* True if inside write transaction */
|
||||
u8 nAux; /* # of auxiliary columns in %_rowid */
|
||||
u8 nAuxNotNull; /* Number of initial not-null aux columns */
|
||||
int iDepth; /* Current depth of the r-tree structure */
|
||||
char *zDb; /* Name of database containing r-tree table */
|
||||
char *zName; /* Name of r-tree table */
|
||||
@ -2893,7 +2894,7 @@ static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){
|
||||
/*
|
||||
** Select a currently unused rowid for a new r-tree record.
|
||||
*/
|
||||
static int newRowid(Rtree *pRtree, i64 *piRowid){
|
||||
static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){
|
||||
int rc;
|
||||
sqlite3_bind_null(pRtree->pWriteRowid, 1);
|
||||
sqlite3_bind_null(pRtree->pWriteRowid, 2);
|
||||
@ -3180,7 +3181,7 @@ static int rtreeUpdate(
|
||||
|
||||
/* Figure out the rowid of the new row. */
|
||||
if( bHaveRowid==0 ){
|
||||
rc = newRowid(pRtree, &cell.iRowid);
|
||||
rc = rtreeNewRowid(pRtree, &cell.iRowid);
|
||||
}
|
||||
*pRowid = cell.iRowid;
|
||||
|
||||
@ -3453,7 +3454,11 @@ static int rtreeSqlInit(
|
||||
sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix);
|
||||
for(ii=0; ii<pRtree->nAux; ii++){
|
||||
if( ii ) sqlite3_str_append(p, ",", 1);
|
||||
sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2);
|
||||
if( ii<pRtree->nAuxNotNull ){
|
||||
sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii);
|
||||
}else{
|
||||
sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2);
|
||||
}
|
||||
}
|
||||
sqlite3_str_appendf(p, " WHERE rowid=?1");
|
||||
zSql = sqlite3_str_finish(p);
|
||||
@ -4222,6 +4227,10 @@ static void rtreecheck(
|
||||
}
|
||||
}
|
||||
|
||||
/* Conditionally include the geopoly code */
|
||||
#ifdef SQLITE_ENABLE_GEOPOLY
|
||||
# include "geopoly.c"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Register the r-tree module with database handle db. This creates the
|
||||
@ -4251,6 +4260,11 @@ int sqlite3RtreeInit(sqlite3 *db){
|
||||
void *c = (void *)RTREE_COORD_INT32;
|
||||
rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_GEOPOLY
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_geopoly_init(db);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
589
ext/rtree/visual01.txt
Normal file
589
ext/rtree/visual01.txt
Normal file
@ -0,0 +1,589 @@
|
||||
#!sqlite3
|
||||
#
|
||||
# This is a visual test case for the geopoly virtual table.
|
||||
#
|
||||
# Run this script in the sqlite3 CLI, and redirect output into an
|
||||
# HTML file. This display the HTML in a webbrowser.
|
||||
#
|
||||
|
||||
/* Test data.
|
||||
** Lots of shapes to be displayed over a 1000x800 canvas.
|
||||
*/
|
||||
CREATE TEMP TABLE basis(name TEXT, jshape TEXT);
|
||||
INSERT INTO basis(name,jshape) VALUES
|
||||
('box-20','[[0,0],[20,0],[20,20],[0,20],[0,0]]'),
|
||||
('house-70','[[0,0],[50,0],[50,50],[25,70],[0,50],[0,0]]'),
|
||||
('line-40','[[0,0],[40,0],[40,5],[0,5],[0,0]]'),
|
||||
('line-80','[[0,0],[80,0],[80,7],[0,7],[0,0]]'),
|
||||
('arrow-50','[[0,0],[25,25],[0,50],[15,25],[0,0]]'),
|
||||
('triangle-30','[[0,0],[30,0],[15,30],[0,0]]'),
|
||||
('angle-30','[[0,0],[30,0],[30,30],[26,30],[26,4],[0,4],[0,0]]'),
|
||||
('star-10','[[1,0],[5,2],[9,0],[7,4],[10,8],[7,7],[5,10],[3,7],[0,8],[3,4],[1,0]]');
|
||||
CREATE TEMP TABLE xform(A,B,C,D,clr);
|
||||
INSERT INTO xform(A,B,clr) VALUES
|
||||
(1,0,'black'),
|
||||
(0.707,0.707,'blue'),
|
||||
(0.5,0.866,'red'),
|
||||
(-0.866,0.5,'green');
|
||||
CREATE TEMP TABLE xyoff(id1,id2,xoff,yoff,PRIMARY KEY(id1,id2,xoff,yoff))
|
||||
WITHOUT ROWID;
|
||||
INSERT INTO xyoff VALUES(1,1,811,659);
|
||||
INSERT INTO xyoff VALUES(1,1,235,550);
|
||||
INSERT INTO xyoff VALUES(1,1,481,620);
|
||||
INSERT INTO xyoff VALUES(1,1,106,494);
|
||||
INSERT INTO xyoff VALUES(1,1,487,106);
|
||||
INSERT INTO xyoff VALUES(1,1,817,595);
|
||||
INSERT INTO xyoff VALUES(1,1,240,504);
|
||||
INSERT INTO xyoff VALUES(1,1,806,457);
|
||||
INSERT INTO xyoff VALUES(1,1,608,107);
|
||||
INSERT INTO xyoff VALUES(1,1,768,662);
|
||||
INSERT INTO xyoff VALUES(1,2,808,528);
|
||||
INSERT INTO xyoff VALUES(1,2,768,528);
|
||||
INSERT INTO xyoff VALUES(1,2,771,171);
|
||||
INSERT INTO xyoff VALUES(1,2,275,671);
|
||||
INSERT INTO xyoff VALUES(1,2,326,336);
|
||||
INSERT INTO xyoff VALUES(1,2,690,688);
|
||||
INSERT INTO xyoff VALUES(1,2,597,239);
|
||||
INSERT INTO xyoff VALUES(1,2,317,528);
|
||||
INSERT INTO xyoff VALUES(1,2,366,223);
|
||||
INSERT INTO xyoff VALUES(1,2,621,154);
|
||||
INSERT INTO xyoff VALUES(1,3,829,469);
|
||||
INSERT INTO xyoff VALUES(1,3,794,322);
|
||||
INSERT INTO xyoff VALUES(1,3,358,387);
|
||||
INSERT INTO xyoff VALUES(1,3,184,444);
|
||||
INSERT INTO xyoff VALUES(1,3,729,500);
|
||||
INSERT INTO xyoff VALUES(1,3,333,523);
|
||||
INSERT INTO xyoff VALUES(1,3,117,595);
|
||||
INSERT INTO xyoff VALUES(1,3,496,201);
|
||||
INSERT INTO xyoff VALUES(1,3,818,601);
|
||||
INSERT INTO xyoff VALUES(1,3,541,343);
|
||||
INSERT INTO xyoff VALUES(1,4,603,248);
|
||||
INSERT INTO xyoff VALUES(1,4,761,649);
|
||||
INSERT INTO xyoff VALUES(1,4,611,181);
|
||||
INSERT INTO xyoff VALUES(1,4,607,233);
|
||||
INSERT INTO xyoff VALUES(1,4,860,206);
|
||||
INSERT INTO xyoff VALUES(1,4,310,231);
|
||||
INSERT INTO xyoff VALUES(1,4,727,539);
|
||||
INSERT INTO xyoff VALUES(1,4,660,661);
|
||||
INSERT INTO xyoff VALUES(1,4,403,133);
|
||||
INSERT INTO xyoff VALUES(1,4,619,331);
|
||||
INSERT INTO xyoff VALUES(2,1,712,578);
|
||||
INSERT INTO xyoff VALUES(2,1,567,313);
|
||||
INSERT INTO xyoff VALUES(2,1,231,423);
|
||||
INSERT INTO xyoff VALUES(2,1,490,175);
|
||||
INSERT INTO xyoff VALUES(2,1,898,353);
|
||||
INSERT INTO xyoff VALUES(2,1,589,483);
|
||||
INSERT INTO xyoff VALUES(2,1,188,462);
|
||||
INSERT INTO xyoff VALUES(2,1,720,106);
|
||||
INSERT INTO xyoff VALUES(2,1,793,380);
|
||||
INSERT INTO xyoff VALUES(2,1,154,396);
|
||||
INSERT INTO xyoff VALUES(2,2,324,218);
|
||||
INSERT INTO xyoff VALUES(2,2,120,327);
|
||||
INSERT INTO xyoff VALUES(2,2,655,133);
|
||||
INSERT INTO xyoff VALUES(2,2,516,603);
|
||||
INSERT INTO xyoff VALUES(2,2,529,572);
|
||||
INSERT INTO xyoff VALUES(2,2,481,212);
|
||||
INSERT INTO xyoff VALUES(2,2,802,107);
|
||||
INSERT INTO xyoff VALUES(2,2,234,509);
|
||||
INSERT INTO xyoff VALUES(2,2,501,269);
|
||||
INSERT INTO xyoff VALUES(2,2,349,553);
|
||||
INSERT INTO xyoff VALUES(2,3,495,685);
|
||||
INSERT INTO xyoff VALUES(2,3,897,372);
|
||||
INSERT INTO xyoff VALUES(2,3,350,681);
|
||||
INSERT INTO xyoff VALUES(2,3,832,257);
|
||||
INSERT INTO xyoff VALUES(2,3,778,149);
|
||||
INSERT INTO xyoff VALUES(2,3,683,426);
|
||||
INSERT INTO xyoff VALUES(2,3,693,217);
|
||||
INSERT INTO xyoff VALUES(2,3,746,317);
|
||||
INSERT INTO xyoff VALUES(2,3,805,369);
|
||||
INSERT INTO xyoff VALUES(2,3,336,585);
|
||||
INSERT INTO xyoff VALUES(2,4,890,255);
|
||||
INSERT INTO xyoff VALUES(2,4,556,565);
|
||||
INSERT INTO xyoff VALUES(2,4,865,555);
|
||||
INSERT INTO xyoff VALUES(2,4,230,293);
|
||||
INSERT INTO xyoff VALUES(2,4,247,251);
|
||||
INSERT INTO xyoff VALUES(2,4,730,563);
|
||||
INSERT INTO xyoff VALUES(2,4,318,282);
|
||||
INSERT INTO xyoff VALUES(2,4,220,431);
|
||||
INSERT INTO xyoff VALUES(2,4,828,336);
|
||||
INSERT INTO xyoff VALUES(2,4,278,525);
|
||||
INSERT INTO xyoff VALUES(3,1,324,656);
|
||||
INSERT INTO xyoff VALUES(3,1,625,362);
|
||||
INSERT INTO xyoff VALUES(3,1,155,570);
|
||||
INSERT INTO xyoff VALUES(3,1,267,433);
|
||||
INSERT INTO xyoff VALUES(3,1,599,121);
|
||||
INSERT INTO xyoff VALUES(3,1,873,498);
|
||||
INSERT INTO xyoff VALUES(3,1,789,520);
|
||||
INSERT INTO xyoff VALUES(3,1,656,378);
|
||||
INSERT INTO xyoff VALUES(3,1,831,601);
|
||||
INSERT INTO xyoff VALUES(3,1,256,471);
|
||||
INSERT INTO xyoff VALUES(3,2,332,258);
|
||||
INSERT INTO xyoff VALUES(3,2,305,463);
|
||||
INSERT INTO xyoff VALUES(3,2,796,341);
|
||||
INSERT INTO xyoff VALUES(3,2,830,229);
|
||||
INSERT INTO xyoff VALUES(3,2,413,271);
|
||||
INSERT INTO xyoff VALUES(3,2,269,140);
|
||||
INSERT INTO xyoff VALUES(3,2,628,441);
|
||||
INSERT INTO xyoff VALUES(3,2,747,643);
|
||||
INSERT INTO xyoff VALUES(3,2,584,435);
|
||||
INSERT INTO xyoff VALUES(3,2,784,314);
|
||||
INSERT INTO xyoff VALUES(3,3,722,233);
|
||||
INSERT INTO xyoff VALUES(3,3,815,421);
|
||||
INSERT INTO xyoff VALUES(3,3,401,267);
|
||||
INSERT INTO xyoff VALUES(3,3,451,650);
|
||||
INSERT INTO xyoff VALUES(3,3,329,485);
|
||||
INSERT INTO xyoff VALUES(3,3,878,370);
|
||||
INSERT INTO xyoff VALUES(3,3,162,616);
|
||||
INSERT INTO xyoff VALUES(3,3,844,183);
|
||||
INSERT INTO xyoff VALUES(3,3,161,216);
|
||||
INSERT INTO xyoff VALUES(3,3,176,676);
|
||||
INSERT INTO xyoff VALUES(3,4,780,128);
|
||||
INSERT INTO xyoff VALUES(3,4,566,121);
|
||||
INSERT INTO xyoff VALUES(3,4,646,120);
|
||||
INSERT INTO xyoff VALUES(3,4,223,557);
|
||||
INSERT INTO xyoff VALUES(3,4,251,117);
|
||||
INSERT INTO xyoff VALUES(3,4,139,209);
|
||||
INSERT INTO xyoff VALUES(3,4,813,597);
|
||||
INSERT INTO xyoff VALUES(3,4,454,538);
|
||||
INSERT INTO xyoff VALUES(3,4,616,198);
|
||||
INSERT INTO xyoff VALUES(3,4,210,159);
|
||||
INSERT INTO xyoff VALUES(4,1,208,415);
|
||||
INSERT INTO xyoff VALUES(4,1,326,665);
|
||||
INSERT INTO xyoff VALUES(4,1,612,133);
|
||||
INSERT INTO xyoff VALUES(4,1,537,513);
|
||||
INSERT INTO xyoff VALUES(4,1,638,438);
|
||||
INSERT INTO xyoff VALUES(4,1,808,269);
|
||||
INSERT INTO xyoff VALUES(4,1,552,121);
|
||||
INSERT INTO xyoff VALUES(4,1,100,189);
|
||||
INSERT INTO xyoff VALUES(4,1,643,664);
|
||||
INSERT INTO xyoff VALUES(4,1,726,378);
|
||||
INSERT INTO xyoff VALUES(4,2,478,409);
|
||||
INSERT INTO xyoff VALUES(4,2,497,507);
|
||||
INSERT INTO xyoff VALUES(4,2,233,148);
|
||||
INSERT INTO xyoff VALUES(4,2,587,237);
|
||||
INSERT INTO xyoff VALUES(4,2,604,166);
|
||||
INSERT INTO xyoff VALUES(4,2,165,455);
|
||||
INSERT INTO xyoff VALUES(4,2,320,258);
|
||||
INSERT INTO xyoff VALUES(4,2,353,496);
|
||||
INSERT INTO xyoff VALUES(4,2,347,495);
|
||||
INSERT INTO xyoff VALUES(4,2,166,622);
|
||||
INSERT INTO xyoff VALUES(4,3,461,332);
|
||||
INSERT INTO xyoff VALUES(4,3,685,278);
|
||||
INSERT INTO xyoff VALUES(4,3,427,594);
|
||||
INSERT INTO xyoff VALUES(4,3,467,346);
|
||||
INSERT INTO xyoff VALUES(4,3,125,548);
|
||||
INSERT INTO xyoff VALUES(4,3,597,680);
|
||||
INSERT INTO xyoff VALUES(4,3,820,445);
|
||||
INSERT INTO xyoff VALUES(4,3,144,330);
|
||||
INSERT INTO xyoff VALUES(4,3,557,434);
|
||||
INSERT INTO xyoff VALUES(4,3,254,315);
|
||||
INSERT INTO xyoff VALUES(4,4,157,339);
|
||||
INSERT INTO xyoff VALUES(4,4,249,220);
|
||||
INSERT INTO xyoff VALUES(4,4,391,323);
|
||||
INSERT INTO xyoff VALUES(4,4,589,429);
|
||||
INSERT INTO xyoff VALUES(4,4,859,592);
|
||||
INSERT INTO xyoff VALUES(4,4,337,680);
|
||||
INSERT INTO xyoff VALUES(4,4,410,288);
|
||||
INSERT INTO xyoff VALUES(4,4,636,596);
|
||||
INSERT INTO xyoff VALUES(4,4,734,433);
|
||||
INSERT INTO xyoff VALUES(4,4,559,549);
|
||||
INSERT INTO xyoff VALUES(5,1,549,607);
|
||||
INSERT INTO xyoff VALUES(5,1,584,498);
|
||||
INSERT INTO xyoff VALUES(5,1,699,116);
|
||||
INSERT INTO xyoff VALUES(5,1,525,524);
|
||||
INSERT INTO xyoff VALUES(5,1,304,667);
|
||||
INSERT INTO xyoff VALUES(5,1,302,232);
|
||||
INSERT INTO xyoff VALUES(5,1,403,149);
|
||||
INSERT INTO xyoff VALUES(5,1,824,403);
|
||||
INSERT INTO xyoff VALUES(5,1,697,203);
|
||||
INSERT INTO xyoff VALUES(5,1,293,689);
|
||||
INSERT INTO xyoff VALUES(5,2,199,275);
|
||||
INSERT INTO xyoff VALUES(5,2,395,393);
|
||||
INSERT INTO xyoff VALUES(5,2,657,642);
|
||||
INSERT INTO xyoff VALUES(5,2,200,655);
|
||||
INSERT INTO xyoff VALUES(5,2,882,234);
|
||||
INSERT INTO xyoff VALUES(5,2,483,565);
|
||||
INSERT INTO xyoff VALUES(5,2,755,640);
|
||||
INSERT INTO xyoff VALUES(5,2,810,305);
|
||||
INSERT INTO xyoff VALUES(5,2,731,655);
|
||||
INSERT INTO xyoff VALUES(5,2,466,690);
|
||||
INSERT INTO xyoff VALUES(5,3,563,584);
|
||||
INSERT INTO xyoff VALUES(5,3,491,117);
|
||||
INSERT INTO xyoff VALUES(5,3,779,292);
|
||||
INSERT INTO xyoff VALUES(5,3,375,637);
|
||||
INSERT INTO xyoff VALUES(5,3,253,553);
|
||||
INSERT INTO xyoff VALUES(5,3,797,514);
|
||||
INSERT INTO xyoff VALUES(5,3,229,480);
|
||||
INSERT INTO xyoff VALUES(5,3,257,194);
|
||||
INSERT INTO xyoff VALUES(5,3,449,555);
|
||||
INSERT INTO xyoff VALUES(5,3,849,630);
|
||||
INSERT INTO xyoff VALUES(5,4,329,286);
|
||||
INSERT INTO xyoff VALUES(5,4,640,197);
|
||||
INSERT INTO xyoff VALUES(5,4,104,150);
|
||||
INSERT INTO xyoff VALUES(5,4,438,272);
|
||||
INSERT INTO xyoff VALUES(5,4,773,226);
|
||||
INSERT INTO xyoff VALUES(5,4,441,650);
|
||||
INSERT INTO xyoff VALUES(5,4,242,340);
|
||||
INSERT INTO xyoff VALUES(5,4,301,435);
|
||||
INSERT INTO xyoff VALUES(5,4,171,397);
|
||||
INSERT INTO xyoff VALUES(5,4,541,619);
|
||||
INSERT INTO xyoff VALUES(6,1,651,301);
|
||||
INSERT INTO xyoff VALUES(6,1,637,137);
|
||||
INSERT INTO xyoff VALUES(6,1,765,643);
|
||||
INSERT INTO xyoff VALUES(6,1,173,296);
|
||||
INSERT INTO xyoff VALUES(6,1,263,192);
|
||||
INSERT INTO xyoff VALUES(6,1,791,302);
|
||||
INSERT INTO xyoff VALUES(6,1,860,601);
|
||||
INSERT INTO xyoff VALUES(6,1,780,445);
|
||||
INSERT INTO xyoff VALUES(6,1,462,214);
|
||||
INSERT INTO xyoff VALUES(6,1,802,207);
|
||||
INSERT INTO xyoff VALUES(6,2,811,685);
|
||||
INSERT INTO xyoff VALUES(6,2,533,531);
|
||||
INSERT INTO xyoff VALUES(6,2,390,614);
|
||||
INSERT INTO xyoff VALUES(6,2,260,580);
|
||||
INSERT INTO xyoff VALUES(6,2,116,377);
|
||||
INSERT INTO xyoff VALUES(6,2,860,458);
|
||||
INSERT INTO xyoff VALUES(6,2,438,590);
|
||||
INSERT INTO xyoff VALUES(6,2,604,562);
|
||||
INSERT INTO xyoff VALUES(6,2,241,242);
|
||||
INSERT INTO xyoff VALUES(6,2,667,298);
|
||||
INSERT INTO xyoff VALUES(6,3,787,698);
|
||||
INSERT INTO xyoff VALUES(6,3,868,521);
|
||||
INSERT INTO xyoff VALUES(6,3,412,587);
|
||||
INSERT INTO xyoff VALUES(6,3,640,131);
|
||||
INSERT INTO xyoff VALUES(6,3,748,410);
|
||||
INSERT INTO xyoff VALUES(6,3,257,244);
|
||||
INSERT INTO xyoff VALUES(6,3,411,195);
|
||||
INSERT INTO xyoff VALUES(6,3,464,356);
|
||||
INSERT INTO xyoff VALUES(6,3,157,339);
|
||||
INSERT INTO xyoff VALUES(6,3,434,505);
|
||||
INSERT INTO xyoff VALUES(6,4,480,671);
|
||||
INSERT INTO xyoff VALUES(6,4,519,228);
|
||||
INSERT INTO xyoff VALUES(6,4,404,513);
|
||||
INSERT INTO xyoff VALUES(6,4,120,538);
|
||||
INSERT INTO xyoff VALUES(6,4,403,663);
|
||||
INSERT INTO xyoff VALUES(6,4,477,677);
|
||||
INSERT INTO xyoff VALUES(6,4,690,154);
|
||||
INSERT INTO xyoff VALUES(6,4,606,498);
|
||||
INSERT INTO xyoff VALUES(6,4,430,665);
|
||||
INSERT INTO xyoff VALUES(6,4,499,273);
|
||||
INSERT INTO xyoff VALUES(7,1,118,526);
|
||||
INSERT INTO xyoff VALUES(7,1,817,522);
|
||||
INSERT INTO xyoff VALUES(7,1,388,638);
|
||||
INSERT INTO xyoff VALUES(7,1,181,265);
|
||||
INSERT INTO xyoff VALUES(7,1,442,332);
|
||||
INSERT INTO xyoff VALUES(7,1,475,282);
|
||||
INSERT INTO xyoff VALUES(7,1,722,633);
|
||||
INSERT INTO xyoff VALUES(7,1,104,394);
|
||||
INSERT INTO xyoff VALUES(7,1,631,262);
|
||||
INSERT INTO xyoff VALUES(7,1,372,392);
|
||||
INSERT INTO xyoff VALUES(7,2,600,413);
|
||||
INSERT INTO xyoff VALUES(7,2,386,223);
|
||||
INSERT INTO xyoff VALUES(7,2,839,174);
|
||||
INSERT INTO xyoff VALUES(7,2,293,410);
|
||||
INSERT INTO xyoff VALUES(7,2,281,391);
|
||||
INSERT INTO xyoff VALUES(7,2,859,387);
|
||||
INSERT INTO xyoff VALUES(7,2,478,347);
|
||||
INSERT INTO xyoff VALUES(7,2,646,690);
|
||||
INSERT INTO xyoff VALUES(7,2,713,234);
|
||||
INSERT INTO xyoff VALUES(7,2,199,588);
|
||||
INSERT INTO xyoff VALUES(7,3,389,256);
|
||||
INSERT INTO xyoff VALUES(7,3,349,542);
|
||||
INSERT INTO xyoff VALUES(7,3,363,345);
|
||||
INSERT INTO xyoff VALUES(7,3,751,302);
|
||||
INSERT INTO xyoff VALUES(7,3,423,386);
|
||||
INSERT INTO xyoff VALUES(7,3,267,444);
|
||||
INSERT INTO xyoff VALUES(7,3,243,182);
|
||||
INSERT INTO xyoff VALUES(7,3,453,658);
|
||||
INSERT INTO xyoff VALUES(7,3,126,345);
|
||||
INSERT INTO xyoff VALUES(7,3,120,472);
|
||||
INSERT INTO xyoff VALUES(7,4,359,654);
|
||||
INSERT INTO xyoff VALUES(7,4,339,516);
|
||||
INSERT INTO xyoff VALUES(7,4,710,452);
|
||||
INSERT INTO xyoff VALUES(7,4,810,560);
|
||||
INSERT INTO xyoff VALUES(7,4,644,692);
|
||||
INSERT INTO xyoff VALUES(7,4,826,327);
|
||||
INSERT INTO xyoff VALUES(7,4,465,462);
|
||||
INSERT INTO xyoff VALUES(7,4,310,456);
|
||||
INSERT INTO xyoff VALUES(7,4,577,613);
|
||||
INSERT INTO xyoff VALUES(7,4,502,555);
|
||||
INSERT INTO xyoff VALUES(8,1,601,620);
|
||||
INSERT INTO xyoff VALUES(8,1,372,683);
|
||||
INSERT INTO xyoff VALUES(8,1,758,399);
|
||||
INSERT INTO xyoff VALUES(8,1,485,552);
|
||||
INSERT INTO xyoff VALUES(8,1,159,563);
|
||||
INSERT INTO xyoff VALUES(8,1,536,303);
|
||||
INSERT INTO xyoff VALUES(8,1,122,263);
|
||||
INSERT INTO xyoff VALUES(8,1,836,435);
|
||||
INSERT INTO xyoff VALUES(8,1,544,146);
|
||||
INSERT INTO xyoff VALUES(8,1,270,277);
|
||||
INSERT INTO xyoff VALUES(8,2,849,281);
|
||||
INSERT INTO xyoff VALUES(8,2,563,242);
|
||||
INSERT INTO xyoff VALUES(8,2,704,463);
|
||||
INSERT INTO xyoff VALUES(8,2,102,165);
|
||||
INSERT INTO xyoff VALUES(8,2,797,524);
|
||||
INSERT INTO xyoff VALUES(8,2,612,426);
|
||||
INSERT INTO xyoff VALUES(8,2,345,372);
|
||||
INSERT INTO xyoff VALUES(8,2,820,376);
|
||||
INSERT INTO xyoff VALUES(8,2,789,156);
|
||||
INSERT INTO xyoff VALUES(8,2,321,466);
|
||||
INSERT INTO xyoff VALUES(8,3,150,332);
|
||||
INSERT INTO xyoff VALUES(8,3,136,152);
|
||||
INSERT INTO xyoff VALUES(8,3,468,528);
|
||||
INSERT INTO xyoff VALUES(8,3,409,192);
|
||||
INSERT INTO xyoff VALUES(8,3,820,216);
|
||||
INSERT INTO xyoff VALUES(8,3,847,249);
|
||||
INSERT INTO xyoff VALUES(8,3,801,267);
|
||||
INSERT INTO xyoff VALUES(8,3,181,670);
|
||||
INSERT INTO xyoff VALUES(8,3,398,563);
|
||||
INSERT INTO xyoff VALUES(8,3,439,576);
|
||||
INSERT INTO xyoff VALUES(8,4,123,309);
|
||||
INSERT INTO xyoff VALUES(8,4,190,496);
|
||||
INSERT INTO xyoff VALUES(8,4,571,531);
|
||||
INSERT INTO xyoff VALUES(8,4,290,255);
|
||||
INSERT INTO xyoff VALUES(8,4,244,412);
|
||||
INSERT INTO xyoff VALUES(8,4,264,596);
|
||||
INSERT INTO xyoff VALUES(8,4,253,420);
|
||||
INSERT INTO xyoff VALUES(8,4,847,536);
|
||||
INSERT INTO xyoff VALUES(8,4,120,288);
|
||||
INSERT INTO xyoff VALUES(8,4,331,639);
|
||||
|
||||
/* Create the geopoly object from test data above */
|
||||
CREATE VIRTUAL TABLE geo1 USING geopoly(type,clr);
|
||||
INSERT INTO geo1(_shape,type,clr)
|
||||
SELECT geopoly_xform(jshape,A,B,-B,A,xoff,yoff), basis.name, xform.clr
|
||||
FROM basis, xform, xyoff
|
||||
WHERE xyoff.id1=basis.rowid AND xyoff.id2=xform.rowid;
|
||||
|
||||
|
||||
/* Query polygon */
|
||||
CREATE TEMP TABLE querypoly(poly JSON, clr TEXT);
|
||||
INSERT INTO querypoly(clr, poly) VALUES
|
||||
('orange', '[[300,300],[400,350],[500,250],[480,500],[400,480],[300,550],[280,450],[320,400],[280,350],[300,300]]');
|
||||
|
||||
/* Generate the HTML */
|
||||
.print '<html>'
|
||||
.print '<h1>Everything</h1>'
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',clr)
|
||||
)
|
||||
FROM geo1;
|
||||
SELECT geopoly_svg(poly,
|
||||
printf('style="fill:%s;fill-opacity:0.5;"',clr)
|
||||
)
|
||||
FROM querypoly;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Overlap Query</h1>'
|
||||
.print '<pre>'
|
||||
.print 'SELECT *'
|
||||
.print ' FROM geo1, querypoly'
|
||||
.print ' WHERE geopoly_overlap(_shape, poly);'
|
||||
.print
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE geopoly_overlap(_shape, poly);
|
||||
.print '</pre>'
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE geopoly_overlap(_shape, poly);
|
||||
SELECT geopoly_svg(poly,
|
||||
printf('style="fill:%s;fill-opacity:0.5;"',clr)
|
||||
)
|
||||
FROM querypoly;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Overlap Query And Result Bounding Box</h1>'
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE geopoly_overlap(_shape, poly);
|
||||
SELECT geopoly_svg(geopoly_bbox(poly),
|
||||
'style="fill:none;stroke:black;stroke-width:3"'
|
||||
)
|
||||
FROM querypoly;
|
||||
SELECT geopoly_svg(poly,
|
||||
printf('style="fill:%s;fill-opacity:0.5;"',clr)
|
||||
)
|
||||
FROM querypoly;
|
||||
SELECT geopoly_svg(geopoly_group_bbox(_shape),
|
||||
'style="fill:none;stroke:red;stroke-width:3"'
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE geopoly_overlap(_shape, poly);
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Bounding-Box Overlap Query</h1>'
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
),
|
||||
geopoly_svg(geopoly_bbox(_shape),
|
||||
'style="fill:none;stroke:black;stroke-width:1"'
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE geopoly_overlap(geopoly_bbox(_shape), geopoly_bbox(poly));
|
||||
SELECT geopoly_svg(poly,
|
||||
printf('style="fill:%s;fill-opacity:0.5;"',clr)
|
||||
)
|
||||
FROM querypoly;
|
||||
SELECT geopoly_svg(geopoly_bbox(poly),
|
||||
'style="fill:none;stroke:black;stroke-width:3"'
|
||||
)
|
||||
FROM querypoly;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Within Query</h1>'
|
||||
.print '<pre>'
|
||||
.print 'SELECT *'
|
||||
.print ' FROM geo1, querypoly'
|
||||
.print ' WHERE geopoly_within(_shape, poly);'
|
||||
.print
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE geopoly_within(_shape, poly);
|
||||
.print '</pre>'
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE geopoly_within(_shape, poly);
|
||||
SELECT geopoly_svg(poly,
|
||||
printf('style="fill:%s;fill-opacity:0.5;"',clr)
|
||||
)
|
||||
FROM querypoly;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Bounding-Box WITHIN Query</h1>'
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
),
|
||||
geopoly_svg(geopoly_bbox(_shape),
|
||||
'style="fill:none;stroke:black;stroke-width:1"'
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE geopoly_within(geopoly_bbox(_shape), geopoly_bbox(poly));
|
||||
SELECT geopoly_svg(poly,
|
||||
printf('style="fill:%s;fill-opacity:0.5;"',clr)
|
||||
)
|
||||
FROM querypoly;
|
||||
SELECT geopoly_svg(geopoly_bbox(poly),
|
||||
'style="fill:none;stroke:black;stroke-width:3"'
|
||||
)
|
||||
FROM querypoly;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Not Overlap Query</h1>'
|
||||
.print '<pre>'
|
||||
.print 'SELECT *'
|
||||
.print ' FROM geo1, querypoly'
|
||||
.print ' WHERE NOT geopoly_overlap(_shape, poly);'
|
||||
.print
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE NOT geopoly_overlap(_shape, poly);
|
||||
.print '</pre>'
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE NOT geopoly_overlap(_shape, poly);
|
||||
SELECT geopoly_svg(poly,
|
||||
printf('style="fill:%s;fill-opacity:0.5;"',clr)
|
||||
)
|
||||
FROM querypoly;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Not Within Query</h1>'
|
||||
.print '<pre>'
|
||||
.print 'SELECT *'
|
||||
.print ' FROM geo1, querypoly'
|
||||
.print ' WHERE NOT geopoly_within(_shape, poly);'
|
||||
.print
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE NOT geopoly_within(_shape, poly);
|
||||
.print '</pre>'
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1, querypoly
|
||||
WHERE NOT geopoly_within(_shape, poly);
|
||||
SELECT geopoly_svg(poly,
|
||||
printf('style="fill:%s;fill-opacity:0.5;"',clr)
|
||||
)
|
||||
FROM querypoly;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Color-Change For Overlapping Elements</h1>'
|
||||
BEGIN;
|
||||
UPDATE geo1
|
||||
SET clr=CASE WHEN rowid IN (SELECT geo1.rowid FROM geo1, querypoly
|
||||
WHERE geopoly_overlap(_shape,poly))
|
||||
THEN 'red' ELSE 'blue' END;
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1;
|
||||
SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"')
|
||||
FROM querypoly;
|
||||
ROLLBACK;
|
||||
.print '</svg>'
|
||||
|
||||
.print '<h1>Color-Change And Move Overlapping Elements</h1>'
|
||||
BEGIN;
|
||||
UPDATE geo1
|
||||
SET clr=CASE WHEN rowid IN (SELECT geo1.rowid FROM geo1, querypoly
|
||||
WHERE geopoly_overlap(_shape,poly))
|
||||
THEN 'red' ELSE '#76ccff' END;
|
||||
UPDATE geo1
|
||||
SET _shape=geopoly_xform(_shape,1,0,0,1,300,0)
|
||||
WHERE geopoly_overlap(_shape,(SELECT poly FROM querypoly));
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1;
|
||||
SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"')
|
||||
FROM querypoly;
|
||||
--ROLLBACK;
|
||||
.print '</svg>'
|
||||
|
||||
|
||||
.print '<h1>Overlap With Translated Query Polygon</h1>'
|
||||
UPDATE querypoly SET poly=geopoly_xform(poly,1,0,0,1,300,0);
|
||||
.print '<svg width="1000" height="800" style="border:1px solid black">'
|
||||
SELECT geopoly_svg(_shape,
|
||||
printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
|
||||
)
|
||||
FROM geo1
|
||||
WHERE geopoly_overlap(_shape,(SELECT poly FROM querypoly));
|
||||
SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"')
|
||||
FROM querypoly;
|
||||
ROLLBACK;
|
||||
.print '</svg>'
|
||||
|
||||
.print '</html>'
|
6
main.mk
6
main.mk
@ -229,7 +229,8 @@ SRC += \
|
||||
SRC += \
|
||||
$(TOP)/ext/rtree/sqlite3rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.c
|
||||
$(TOP)/ext/rtree/rtree.c \
|
||||
$(TOP)/ext/rtree/geopoly.c
|
||||
SRC += \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/session/sqlite3session.h
|
||||
@ -475,7 +476,8 @@ EXTHDR += \
|
||||
$(TOP)/ext/fts3/fts3_hash.h \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/rtree.h
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/geopoly.c
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
EXTHDR += \
|
||||
|
79
manifest
79
manifest
@ -1,11 +1,11 @@
|
||||
C Ensure\sb-tree\smutexes\sare\salways\sheld\swhen\ssqlite3FindTable()\sis\scalled.\sDo\nnot\sinvoke\sthe\sauthorizer\scallback\swhen\sparsing\sschema\sitems\sas\spart\sof\sALTER\nTABLE\scommands.\sFix\stest\sscript\sissues.
|
||||
D 2018-08-31T18:23:53.268
|
||||
C Merge\sfixes\sand\senhancements\sfrom\strunk.
|
||||
D 2018-09-01T15:49:13.832
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 2729786d5d188974913f07ea63cc84cd42cb9cac5f4aac823c40105e68e22f63
|
||||
F Makefile.in 6b650013511fd9d8b094203ac268af9220d292cc7d4e1bc9fbca15aacd8c7995
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 2e6eec0444dd80730b678b009cbe7fb9382dc3c5e8f45f554730203678cdd782
|
||||
F README.md 7764d56778d567913ef11c82da9ab94aefa0826f7c243351e4e2d7adaef6f373
|
||||
F Makefile.msc d37bb24f0910744b555d77bea3d2f31e412caaf0c8ac6ec76a3d312cb3cf52ce
|
||||
F README.md 377233394b905d3b2e2b33741289e093bc93f2e7adbe00923b2c5958c9a9edee
|
||||
F VERSION d3e3afdec1165a5e593dcdfffd8e0f33a2b0186067eb51a073ef6c4aec34923d
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@ -33,8 +33,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure a46cba271ae08d635a1f331384c04563bdd37adb3d63cbdcffb1d91babfb64f5 x
|
||||
F configure.ac 18c93e8bbeec8254832c4ea90eb06e7187fd150ef098baed02467eeb374afb17
|
||||
F configure e80ab4e1f5c63a6979971712d35142ad69ef40da6ee4e4df3456be1a77439124 x
|
||||
F configure.ac 3552d3aecade98a9d4b64bceb48ffb7726cbc85902efde956812942f060fbd0a
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
F doc/lemon.html ac63db056bce24b7368e29319cd1a7eb5f1798cc85922d96a80b6c3a4ff9f51b
|
||||
@ -276,7 +276,7 @@ F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb
|
||||
F ext/misc/btreeinfo.c 78c8c57d325185ccc04b7679e5b020e34a4d9c87453e6b7ac943d0a26cee3256
|
||||
F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
|
||||
F ext/misc/closure.c fe928228e8dfb2f00227311c203ccba9c2e5561f4f6de6da87e5b4a30cd8af15
|
||||
F ext/misc/completion.c e75b8886a2531f9a7ec02dab5f179bb37e6bd46b5da7665a6cbf2dfbe2daa483
|
||||
F ext/misc/completion.c fc811dda86d899c15848079c32cad40c181da1dd7a1a4f8d768a2c6ce07a1904
|
||||
F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
|
||||
F ext/misc/csv.c 65297bcce8d5acd5aadef42acbe739aef5a2ef5e74c7b73361ca19f3e21de657
|
||||
F ext/misc/dbdump.c 12389a10c410fadf1e68eeb382def92d5a7fa9ce7cce4fb86a736fa2bac1000a
|
||||
@ -284,7 +284,7 @@ F ext/misc/eval.c 6ea9b22a5fa0dd973b67ca4e53555be177bc0b7b263aadf1024429457c82c0
|
||||
F ext/misc/fileio.c 48c7751c78fc4cdd29d8c862fd2f3f98bbfefa2a3cf1ca1496df4bf02eb8cded
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c 696c596de45d991e6c4617b5a3cb4cc60d231aa4be10edea7d27a4008df2f545
|
||||
F ext/misc/json1.c 34a31eac76aeec269657f6f84a72533600d511005efa5dd97034909a2a0fbc9a
|
||||
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
|
||||
F ext/misc/mmapwarm.c 70b618f2d0bde43fae288ad0b7498a629f2b6f61b50a27e06fae3cd23c83af29
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
@ -359,7 +359,8 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782
|
||||
F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f
|
||||
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c cb6d4bd43c118354fe5b5213843da058259467ecdbac0c6f71ead0fd89acf4ec
|
||||
F ext/rtree/geopoly.c 8ed95c3233ea38b6688cda8c07685cb6bf6e6e0b14208bad343c12c9f8252d3f
|
||||
F ext/rtree/rtree.c ce94cbb319423fd739702582dde47371aec8ad85207d517c41bdbf75a7ffd737
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test 309afc04d4287542b2cd74f933296832cc681c7b014d9405cb329b62053a5349
|
||||
F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e541220fe2
|
||||
@ -385,6 +386,7 @@ F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae926833
|
||||
F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28
|
||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F ext/rtree/visual01.txt 17c3afefc208c375607aa82242e97fa79c316e539bcd0b7b3e59344c69445d05
|
||||
F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
|
||||
F ext/session/session1.test 4532116484f525110eb4cfff7030c59354c0cde9def4d109466b0df2b35ad5cc
|
||||
F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0
|
||||
@ -420,7 +422,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk bbd82ed499413e8d56a00eaa124d4946650f327ea9ee312006ce4674b441dc3c
|
||||
F main.mk 1db6df4bff24ed6684917e3fe311ce28f5924d6417c698fe4326f7cadf02df31
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@ -450,7 +452,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3
|
||||
F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
|
||||
F src/delete.c 107e28d3ef8bd72fd11953374ca9107cd74e8b09c3ded076a6048742d26ce7d2
|
||||
F src/expr.c e7d04a23bc4f42f0ad32b4d5c52a3fff13e113d68192c10d7c6c7ebe47a5f3f1
|
||||
F src/expr.c 92dc4e104b06d06ffeacbd1a4dc0a520daf37f6156278fb6ece5e90e2ca6b610
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c f59253c0be4b1e9dfcb073b6d6d6ab83090ae50c08b5c113b76013c4b157cd6a
|
||||
F src/func.c 7c288b4ce309b5a8b8473514b88e1f8e69a80134509a8c0db8e39c858e367e7f
|
||||
@ -462,7 +464,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c c723716f0de7aa0a679300f7d3541c89645f4a9882161cecdb3093fc07f8cc4b
|
||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||
F src/loadext.c 6aae5739198d96c51ae6eb97c4a5b1744c22ed7a5a565a5399a717780d48a36b
|
||||
F src/main.c 187011ff7a091ff4b8bea9481a42789c0fa094715b4e5d89352fb63377673490
|
||||
F src/main.c 1f54ee71990bfbf4cdc2dc79bdc33e7c4f54eef6922447b4c910f9b5885a4478
|
||||
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
@ -485,25 +487,25 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c d6ee0c3b3f221dd5f3cec95f0400a581c516d04ea16a2916bba17c55127d8e06
|
||||
F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 705de01dff9c3df9739c37a6d3b58cd2b1734fdabcef829b16cdc7721a9eeaa4
|
||||
F src/pager.c a0d8f686ef64549ad5b356fd30429bd9ee7a06dd42b4d6faa096352ff26b1c5b
|
||||
F src/pager.h ecc554a55bc55d1c4ba5e17137b72e238e00bd81e72ff2662d8b9c8c10ae3963
|
||||
F src/parse.y b3ca0ebaba6abe775e22c380fecfea17776ea150a6fb8e419a2a2274e478bc01
|
||||
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
|
||||
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
|
||||
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
|
||||
F src/pragma.c 873b767f233932e97cbffd094aa61928be90aca03f946a94bb29ce5695e4885b
|
||||
F src/pragma.c 79abc65c08d2754048efee3ba99fe91863dfeab0ba699a4439fa5053ec87cf36
|
||||
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
|
||||
F src/prepare.c f8e260d940a0e08494c0f30744521b2f832d7263eca9d02b050cea0ba144b097
|
||||
F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 352c6af1a99441206ff62a6f7429dbf537827f42c428639695220b9c8639e33b
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
|
||||
F src/select.c ae7396a314cc1bb1d767947cd57094e3a9ffcbb155ebc1b1c391e028c44a9a04
|
||||
F src/shell.c.in 6e0aad854be738a5d0368940459399be211e9ac43aebe92bb9ed46cfe38d0e1f
|
||||
F src/sqlite.h.in 82b5768e36ce796ecf93c73bd88bad99def831ce7d470138e213ac693bf4ceab
|
||||
F src/sqlite.h.in cdf2a539cd0570322a94bcb97c01c56feb1be0657ec7cfb8273c89d19fff87a9
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
|
||||
F src/sqliteInt.h 83b8d196810c41eb0818793f07f9393b0a5b9173a16588ac9436245b279d3a11
|
||||
F src/sqliteInt.h 5444fef2e1d7e295e89d570b4abfc9a4170f1599313e0fcef3e5af7695c955c6
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@ -565,28 +567,28 @@ F src/tokenize.c 9f55961518f77793edd56eee860ecf035d4370ebbb0726ad2f6cada6637fd16
|
||||
F src/treeview.c e7a7f90552bb418533cdd0309b5eb71d4effa50165b880fc8c2001e613577e5f
|
||||
F src/trigger.c d3d78568f37fb2e6cdcc2d1e7b60156f15b0b600adec55b83c5d42f6cad250bd
|
||||
F src/update.c 345ce35eb1332eb4829857aa8b1f65a614b07dae91d0346c0dc2baacafbcc51b
|
||||
F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88
|
||||
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
|
||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||
F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855
|
||||
F src/vdbe.c 7a8fc343ce0d852fe1f37c1d7d763a9f22f6f26d2c594293d77313acbc527821
|
||||
F src/vdbe.c dea0115a61f31227a116930c2f16b97f0a0e90abc7b87b09d1dfb8dc525b147b
|
||||
F src/vdbe.h 5081dcc497777efe5e9ebe7330d283a044a005e4bdda2e2e984f03bf89a0d907
|
||||
F src/vdbeInt.h 8ea493d994c6697cf7bccc60583a80a0222560490410f60f1113e90d36643ce0
|
||||
F src/vdbeInt.h f1f35f70460698d8f5a2bdef1001114babf318e2983a067804e2ae077d8e9827
|
||||
F src/vdbeapi.c 2ba821c5929a2769e4b217dd85843479c718b8989d414723ec8af0616a83d611
|
||||
F src/vdbeaux.c f03d4a1961ec282abaec5dbf7e5576ddb1eb01e6157335a232d8d9e57fd5eca1
|
||||
F src/vdbeaux.c 1ee77344fe9fd6ac11fae6f0150f81e0eadf349a9957340089cf82284e6b379a
|
||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||
F src/vdbemem.c 0dc99941388a867a4dc77a8bed5dfc6024ee9c3ef147a09de844a6629086ec0c
|
||||
F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
|
||||
F src/vdbemem.c 81329ab760e4ec0162119d9cd10193e0303c45c5935bb20c7ae9139d44dd6641
|
||||
F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
|
||||
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
||||
F src/vtab.c 8665561f244c137a2d17b5c3e5910d7303054fe841c5d510e53f23beb0089594
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c e4bcbd90072e9626126d6f3b8411159a0b984c1b9628d15237776578d5eda12d
|
||||
F src/wal.c df50883d93689d009be5ad9bdc4e53a4ee45fcc291087ec9272569d00b360791
|
||||
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
|
||||
F src/walker.c ba7225773931760cf60bf22f34d0cce2588df7ce5ce0f215a52eb88234b55ac4
|
||||
F src/where.c 155809967fbab889374dedf970ea6561b8fb519fcb165d6ba00776552ecc5cde
|
||||
F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
|
||||
F src/wherecode.c 2b6cd1b27736cc803060289e04ecf9849976106f4077aa67d1a2c0e3ec420159
|
||||
F src/whereexpr.c 5a57a974aeadef4443b39bd44594fdf0c884b62a4c72286de880999018df8317
|
||||
F src/whereexpr.c d87df2c00ecc0c2ef4409562608d19cec259a6a03ca72b86fc999db9c07ce119
|
||||
F src/window.c 4b503da928dace3e845b891381a4d98eeb8c5744313ae3643df8d8d21fdcca65
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
@ -1240,7 +1242,7 @@ F test/selectD.test fc20452847a01775710090383cfb4423275d2f745fed61f34fbf37573ac0
|
||||
F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf
|
||||
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
|
||||
F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae8840
|
||||
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
|
||||
F test/server1.test c2b00864514a68a0e6fd518659dc95d0050307a357a08969872bef027d785dc4
|
||||
F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be
|
||||
F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb
|
||||
F test/sessionfuzz.c b0fcdcf757451957e17396a3af5171f1fdf9b2babc81da9fa35675df46c4729a
|
||||
@ -1273,11 +1275,12 @@ F test/skipscan2.test ef143c6e4a5ba4f19c1d1e3f517811f7942bdf2142736cc568feb34e0b
|
||||
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
|
||||
F test/skipscan6.test 0b4cd1b4ac9f84d91454df513c99a4932fa07e8f27b8049bea605068b3e34ac7
|
||||
F test/snapshot.test fef12fc5c16ff21c4748509401cfba7d9a3d91156f1bfe23fb881d3bfc65ddfe
|
||||
F test/snapshot2.test 925e42427e923262db63c9d7155183f889e3e99feaedec4075f659e51608344f
|
||||
F test/snapshot3.test 9719443594a04778861bd20d12596c5f880af177d6cd62f111da3198cafc6096
|
||||
F test/snapshot_fault.test 52c5e97ebd218846a8ae2da4d147d3e77d71f963
|
||||
F test/snapshot_up.test b778a04561a67b8bfde828f473a8d31dbde23e3f648e36237e0369421e08f23c
|
||||
F test/snapshot.test a504f2e7009f512ef66c719f0ea1c55a556bdaf1e1312c80a04d46fc1a3e9632
|
||||
F test/snapshot2.test 4fc84a0121e882d6980333bf14dfc1143dfb94f5afbb909c084977a945b45beb
|
||||
F test/snapshot3.test d6ec952e437e5c06a293d0f5ec1be1b45771d46d93bccfb3818ca2617dcb11e7
|
||||
F test/snapshot4.test 0f7e6bd6f1370d112ee820c541d0dd0e7b8ab4ea77429e65106d81c9ad2185a6
|
||||
F test/snapshot_fault.test 508ae6f211d4991e9ff3b5080aeb0a179bf6755138aabeac4bca8083044d895a
|
||||
F test/snapshot_up.test 93fec2d847ec12e3bae0f6486da2abc965a606e099e4e870454045f5f56f71ba
|
||||
F test/soak.test 18944cf21b94a7fe0df02016a6ee1e9632bc4e8d095a0cb49d95e15d5cca2d5c
|
||||
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
|
||||
F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b
|
||||
@ -1548,7 +1551,7 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2
|
||||
F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
|
||||
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test 42b97dcd3d7c2f5f9439e41b0983e0c6a5718d8b874e9d5e82d3cd25a50ffcf7
|
||||
F test/view.test 226fb71e37be61854f3a01929ae0a7e14584d6aef5c459bb0a22318f0b6dd210
|
||||
F test/vtab1.test 8f91b9538d1404c3932293a588c4344218a0c94792d4289bb55e41020e7b3fff
|
||||
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
@ -1697,7 +1700,7 @@ F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae42026
|
||||
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
|
||||
F tool/mksqlite3c.tcl 7fe318ab6e0f8b6f59a1268b9e61b403a7885418b59c43fce9974228eab5a8da
|
||||
F tool/mksqlite3c.tcl 5fed3d75069d8f66f202d3b5200b0cea4aa7108481acd06732a06fdd42eb83a2
|
||||
F tool/mksqlite3h.tcl 080873e3856eceb9d289a08a00c4b30f875ea3feadcbece796bd509b1532792c
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
@ -1759,7 +1762,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P f3c27d916d4837f8fc3dd812bd004535f04c7a53bd2a0a2419613275f48bec76
|
||||
R 81cc7609c3c0787876d931405d4b6723
|
||||
U dan
|
||||
Z 6c4368e1a20fe0bd9edcc5b54d5e689a
|
||||
P eac2aa7dce577f1998cc2078dd8ac384070f8acf1ceb565999a5cf719092024e c1aca7673ab04740bc8ad76af0a72a229c79a0cd51cf84d1c689a77424ff17c6
|
||||
R 34f28ccab2f7f9a4a506a2d90442b60b
|
||||
U drh
|
||||
Z 50f92f34e3d19f5b5187cc33c2a11ab3
|
||||
|
@ -1 +1 @@
|
||||
eac2aa7dce577f1998cc2078dd8ac384070f8acf1ceb565999a5cf719092024e
|
||||
589186c083ff3af8d5a6d5ad34e1cefea57806ebf3831ea3bf5a48ef1e173140
|
@ -3741,7 +3741,7 @@ expr_code_doover:
|
||||
** "glob(B,A). We want to use the A in "A glob B" to test
|
||||
** for function overloading. But we use the B term in "glob(B,A)".
|
||||
*/
|
||||
if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
|
||||
if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){
|
||||
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
|
||||
}else if( nFarg>0 ){
|
||||
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
|
||||
|
@ -1329,6 +1329,7 @@ const char *sqlite3ErrName(int rc){
|
||||
switch( rc ){
|
||||
case SQLITE_OK: zName = "SQLITE_OK"; break;
|
||||
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
|
||||
case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break;
|
||||
case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
|
||||
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
|
||||
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
|
||||
|
13
src/pager.c
13
src/pager.c
@ -997,8 +997,12 @@ static int assert_pager_state(Pager *p){
|
||||
** to "print *pPager" in gdb:
|
||||
**
|
||||
** (gdb) printf "%s", print_pager_state(pPager)
|
||||
**
|
||||
** This routine has external linkage in order to suppress compiler warnings
|
||||
** about an unused function. It is enclosed within SQLITE_DEBUG and so does
|
||||
** not appear in normal builds.
|
||||
*/
|
||||
static char *print_pager_state(Pager *p){
|
||||
char *print_pager_state(Pager *p){
|
||||
static char zRet[1024];
|
||||
|
||||
sqlite3_snprintf(1024, zRet,
|
||||
@ -7278,13 +7282,6 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){
|
||||
int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
|
||||
u8 eOld = pPager->journalMode; /* Prior journalmode */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* The print_pager_state() routine is intended to be used by the debugger
|
||||
** only. We invoke it once here to suppress a compiler warning. */
|
||||
print_pager_state(pPager);
|
||||
#endif
|
||||
|
||||
|
||||
/* The eMode parameter is always valid */
|
||||
assert( eMode==PAGER_JOURNALMODE_DELETE
|
||||
|| eMode==PAGER_JOURNALMODE_TRUNCATE
|
||||
|
@ -2222,7 +2222,6 @@ static int pragmaVtabConnect(
|
||||
}
|
||||
if( i==0 ){
|
||||
sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
|
||||
cSep = ',';
|
||||
i++;
|
||||
}
|
||||
j = 0;
|
||||
|
52
src/rowset.c
52
src/rowset.c
@ -124,30 +124,23 @@ struct RowSet {
|
||||
#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */
|
||||
|
||||
/*
|
||||
** Turn bulk memory into a RowSet object. N bytes of memory
|
||||
** are available at pSpace. The db pointer is used as a memory context
|
||||
** for any subsequent allocations that need to occur.
|
||||
** Return a pointer to the new RowSet object.
|
||||
**
|
||||
** It must be the case that N is sufficient to make a Rowset. If not
|
||||
** an assertion fault occurs.
|
||||
**
|
||||
** If N is larger than the minimum, use the surplus as an initial
|
||||
** allocation of entries available to be filled.
|
||||
** Allocate a RowSet object. Return NULL if a memory allocation
|
||||
** error occurs.
|
||||
*/
|
||||
RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
|
||||
RowSet *p;
|
||||
assert( N >= ROUND8(sizeof(*p)) );
|
||||
p = pSpace;
|
||||
p->pChunk = 0;
|
||||
p->db = db;
|
||||
p->pEntry = 0;
|
||||
p->pLast = 0;
|
||||
p->pForest = 0;
|
||||
p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
|
||||
p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
|
||||
p->rsFlags = ROWSET_SORTED;
|
||||
p->iBatch = 0;
|
||||
RowSet *sqlite3RowSetInit(sqlite3 *db){
|
||||
RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p));
|
||||
if( p ){
|
||||
int N = sqlite3DbMallocSize(db, p);
|
||||
p->pChunk = 0;
|
||||
p->db = db;
|
||||
p->pEntry = 0;
|
||||
p->pLast = 0;
|
||||
p->pForest = 0;
|
||||
p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
|
||||
p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
|
||||
p->rsFlags = ROWSET_SORTED;
|
||||
p->iBatch = 0;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -156,7 +149,8 @@ RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
|
||||
** the RowSet has allocated over its lifetime. This routine is
|
||||
** the destructor for the RowSet.
|
||||
*/
|
||||
void sqlite3RowSetClear(RowSet *p){
|
||||
void sqlite3RowSetClear(void *pArg){
|
||||
RowSet *p = (RowSet*)pArg;
|
||||
struct RowSetChunk *pChunk, *pNextChunk;
|
||||
for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
|
||||
pNextChunk = pChunk->pNextChunk;
|
||||
@ -170,6 +164,16 @@ void sqlite3RowSetClear(RowSet *p){
|
||||
p->rsFlags = ROWSET_SORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
** Deallocate all chunks from a RowSet. This frees all memory that
|
||||
** the RowSet has allocated over its lifetime. This routine is
|
||||
** the destructor for the RowSet.
|
||||
*/
|
||||
void sqlite3RowSetDelete(void *pArg){
|
||||
sqlite3RowSetClear(pArg);
|
||||
sqlite3DbFree(((RowSet*)pArg)->db, pArg);
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate a new RowSetEntry object that is associated with the
|
||||
** given RowSet. Return a pointer to the new and completely uninitialized
|
||||
|
@ -472,6 +472,7 @@ int sqlite3_exec(
|
||||
*/
|
||||
#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
|
||||
#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
|
||||
#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8))
|
||||
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
|
||||
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
|
||||
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
|
||||
@ -6440,6 +6441,7 @@ struct sqlite3_index_info {
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
|
||||
#define SQLITE_INDEX_CONSTRAINT_IS 72
|
||||
#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
|
||||
|
||||
/*
|
||||
** CAPI3REF: Register A Virtual Table Implementation
|
||||
@ -9052,11 +9054,11 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
||||
**
|
||||
** ^A call to sqlite3_snapshot_open() will fail to open if the specified
|
||||
** snapshot has been overwritten by a [checkpoint]. In this case
|
||||
** SQLITE_BUSY_SNAPSHOT is returned.
|
||||
** SQLITE_ERROR_SNAPSHOT is returned.
|
||||
**
|
||||
** If there is already a read transaction open when this function is
|
||||
** invoked, then the same read transaction remains open (on the same
|
||||
** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_BUSY_SNAPSHOT
|
||||
** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
|
||||
** is returned. If another error code - for example SQLITE_PROTOCOL or an
|
||||
** SQLITE_IOERR error code - is returned, then the final state of the
|
||||
** read transaction is undefined. If SQLITE_OK is returned, then the
|
||||
|
@ -791,7 +791,8 @@ typedef INT16_TYPE LogEst;
|
||||
# if defined(__SIZEOF_POINTER__)
|
||||
# define SQLITE_PTRSIZE __SIZEOF_POINTER__
|
||||
# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(_M_ARM) || defined(__arm__) || defined(__x86)
|
||||
defined(_M_ARM) || defined(__arm__) || defined(__x86) || \
|
||||
(defined(__TOS_AIX__) && !defined(__64BIT__))
|
||||
# define SQLITE_PTRSIZE 4
|
||||
# else
|
||||
# define SQLITE_PTRSIZE 8
|
||||
@ -832,7 +833,7 @@ typedef INT16_TYPE LogEst;
|
||||
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
|
||||
defined(__arm__)
|
||||
defined(__arm__) || defined(_M_ARM64)
|
||||
# define SQLITE_BYTEORDER 1234
|
||||
# elif defined(sparc) || defined(__ppc__)
|
||||
# define SQLITE_BYTEORDER 4321
|
||||
@ -3856,8 +3857,9 @@ u32 sqlite3BitvecSize(Bitvec*);
|
||||
int sqlite3BitvecBuiltinTest(int,int*);
|
||||
#endif
|
||||
|
||||
RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
|
||||
void sqlite3RowSetClear(RowSet*);
|
||||
RowSet *sqlite3RowSetInit(sqlite3*);
|
||||
void sqlite3RowSetDelete(void*);
|
||||
void sqlite3RowSetClear(void*);
|
||||
void sqlite3RowSetInsert(RowSet*, i64);
|
||||
int sqlite3RowSetTest(RowSet*, int iBatch, i64);
|
||||
int sqlite3RowSetNext(RowSet*, i64*);
|
||||
|
@ -204,10 +204,12 @@ void sqlite3UpsertDoUpdate(
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
sqlite3 *db = pParse->db;
|
||||
SrcList *pSrc; /* FROM clause for the UPDATE */
|
||||
int iDataCur = pUpsert->iDataCur;
|
||||
int iDataCur;
|
||||
|
||||
assert( v!=0 );
|
||||
assert( pUpsert!=0 );
|
||||
VdbeNoopComment((v, "Begin DO UPDATE of UPSERT"));
|
||||
iDataCur = pUpsert->iDataCur;
|
||||
if( pIdx && iCur!=iDataCur ){
|
||||
if( HasRowid(pTab) ){
|
||||
int regRowid = sqlite3GetTempReg(pParse);
|
||||
|
40
src/vdbe.c
40
src/vdbe.c
@ -502,7 +502,7 @@ static void memTracePrint(Mem *p){
|
||||
}else if( p->flags & MEM_Real ){
|
||||
printf(" r:%g", p->u.r);
|
||||
#endif
|
||||
}else if( p->flags & MEM_RowSet ){
|
||||
}else if( sqlite3VdbeMemIsRowSet(p) ){
|
||||
printf(" (rowset)");
|
||||
}else{
|
||||
char zBuf[200];
|
||||
@ -5914,11 +5914,11 @@ case OP_RowSetAdd: { /* in1, in2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
assert( (pIn2->flags & MEM_Int)!=0 );
|
||||
if( (pIn1->flags & MEM_RowSet)==0 ){
|
||||
sqlite3VdbeMemSetRowSet(pIn1);
|
||||
if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
|
||||
if( (pIn1->flags & MEM_Blob)==0 ){
|
||||
if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
|
||||
}
|
||||
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
|
||||
assert( sqlite3VdbeMemIsRowSet(pIn1) );
|
||||
sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5934,8 +5934,9 @@ case OP_RowSetRead: { /* jump, in1, out3 */
|
||||
i64 val;
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( (pIn1->flags & MEM_RowSet)==0
|
||||
|| sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
|
||||
assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) );
|
||||
if( (pIn1->flags & MEM_Blob)==0
|
||||
|| sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0
|
||||
){
|
||||
/* The boolean index is empty */
|
||||
sqlite3VdbeMemSetNull(pIn1);
|
||||
@ -5984,20 +5985,19 @@ case OP_RowSetTest: { /* jump, in1, in3 */
|
||||
/* If there is anything other than a rowset object in memory cell P1,
|
||||
** delete it now and initialize P1 with an empty rowset
|
||||
*/
|
||||
if( (pIn1->flags & MEM_RowSet)==0 ){
|
||||
sqlite3VdbeMemSetRowSet(pIn1);
|
||||
if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
|
||||
if( (pIn1->flags & MEM_Blob)==0 ){
|
||||
if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
|
||||
}
|
||||
|
||||
assert( sqlite3VdbeMemIsRowSet(pIn1) );
|
||||
assert( pOp->p4type==P4_INT32 );
|
||||
assert( iSet==-1 || iSet>=0 );
|
||||
if( iSet ){
|
||||
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
|
||||
exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i);
|
||||
VdbeBranchTaken(exists!=0,2);
|
||||
if( exists ) goto jump_to_p2;
|
||||
}
|
||||
if( iSet>=0 ){
|
||||
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
|
||||
sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -6061,7 +6061,7 @@ case OP_Program: { /* jump */
|
||||
** of the current program, and the memory required at runtime to execute
|
||||
** the trigger program. If this trigger has been fired before, then pRt
|
||||
** is already allocated. Otherwise, it must be initialized. */
|
||||
if( (pRt->flags&MEM_Frame)==0 ){
|
||||
if( (pRt->flags&MEM_Blob)==0 ){
|
||||
/* SubProgram.nMem is set to the number of memory cells used by the
|
||||
** program stored in SubProgram.aOp. As well as these, one memory
|
||||
** cell is required for each cursor used by the program. Set local
|
||||
@ -6079,8 +6079,10 @@ case OP_Program: { /* jump */
|
||||
goto no_mem;
|
||||
}
|
||||
sqlite3VdbeMemRelease(pRt);
|
||||
pRt->flags = MEM_Frame;
|
||||
pRt->u.pFrame = pFrame;
|
||||
pRt->flags = MEM_Blob|MEM_Dyn;
|
||||
pRt->z = (char*)pFrame;
|
||||
pRt->n = nByte;
|
||||
pRt->xDel = sqlite3VdbeFrameMemDel;
|
||||
|
||||
pFrame->v = p;
|
||||
pFrame->nChildMem = nMem;
|
||||
@ -6096,6 +6098,9 @@ case OP_Program: { /* jump */
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
pFrame->anExec = p->anExec;
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
pFrame->iFrameMagic = SQLITE_FRAME_MAGIC;
|
||||
#endif
|
||||
|
||||
pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
|
||||
for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
|
||||
@ -6103,7 +6108,8 @@ case OP_Program: { /* jump */
|
||||
pMem->db = db;
|
||||
}
|
||||
}else{
|
||||
pFrame = pRt->u.pFrame;
|
||||
pFrame = (VdbeFrame*)pRt->z;
|
||||
assert( pRt->xDel==sqlite3VdbeFrameMemDel );
|
||||
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem
|
||||
|| (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
|
||||
assert( pProgram->nCsr==pFrame->nChildCsr );
|
||||
|
@ -169,6 +169,9 @@ struct VdbeFrame {
|
||||
void *token; /* Copy of SubProgram.token */
|
||||
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
|
||||
AuxData *pAuxData; /* Linked list of auxdata allocations */
|
||||
#if SQLITE_DEBUG
|
||||
u32 iFrameMagic; /* magic number for sanity checking */
|
||||
#endif
|
||||
int nCursor; /* Number of entries in apCsr */
|
||||
int pc; /* Program Counter in parent (calling) frame */
|
||||
int nOp; /* Size of aOp array */
|
||||
@ -179,6 +182,13 @@ struct VdbeFrame {
|
||||
int nDbChange; /* Value of db->nChange */
|
||||
};
|
||||
|
||||
/* Magic number for sanity checking on VdbeFrame objects */
|
||||
#define SQLITE_FRAME_MAGIC 0x879fb71e
|
||||
|
||||
/*
|
||||
** Return a pointer to the array of registers allocated for use
|
||||
** by a VdbeFrame.
|
||||
*/
|
||||
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
|
||||
|
||||
/*
|
||||
@ -193,8 +203,6 @@ struct sqlite3_value {
|
||||
int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
|
||||
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
|
||||
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
||||
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
|
||||
VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
|
||||
} u;
|
||||
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
|
||||
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
||||
@ -238,8 +246,8 @@ struct sqlite3_value {
|
||||
#define MEM_Real 0x0008 /* Value is a real number */
|
||||
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
||||
#define MEM_AffMask 0x001f /* Mask of affinity bits */
|
||||
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
|
||||
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
|
||||
/* Available 0x0020 */
|
||||
/* Available 0x0040 */
|
||||
#define MEM_Undefined 0x0080 /* Value is undefined */
|
||||
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
|
||||
#define MEM_TypeMask 0xc1ff /* Mask of type bits */
|
||||
@ -266,7 +274,7 @@ struct sqlite3_value {
|
||||
** that needs to be deallocated to avoid a leak.
|
||||
*/
|
||||
#define VdbeMemDynamic(X) \
|
||||
(((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
|
||||
(((X)->flags&(MEM_Agg|MEM_Dyn))!=0)
|
||||
|
||||
/*
|
||||
** Clear any existing type flags from a Mem and replace them with f
|
||||
@ -479,7 +487,10 @@ void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
|
||||
void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
|
||||
void sqlite3VdbeMemSetNull(Mem*);
|
||||
void sqlite3VdbeMemSetZeroBlob(Mem*,int);
|
||||
void sqlite3VdbeMemSetRowSet(Mem*);
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3VdbeMemIsRowSet(const Mem*);
|
||||
#endif
|
||||
int sqlite3VdbeMemSetRowSet(Mem*);
|
||||
int sqlite3VdbeMemMakeWriteable(Mem*);
|
||||
int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
||||
i64 sqlite3VdbeIntValue(Mem*);
|
||||
@ -500,7 +511,11 @@ const char *sqlite3OpcodeName(int);
|
||||
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
|
||||
int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
|
||||
int sqlite3VdbeCloseStatement(Vdbe *, int);
|
||||
void sqlite3VdbeFrameDelete(VdbeFrame*);
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3VdbeFrameIsValid(VdbeFrame*);
|
||||
#endif
|
||||
void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */
|
||||
void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */
|
||||
int sqlite3VdbeFrameRestore(VdbeFrame *);
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
|
||||
|
@ -316,7 +316,7 @@ int sqlite3VdbeExplainParent(Parse *pParse){
|
||||
void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
|
||||
if( pParse->explain==2 ){
|
||||
char *zMsg;
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
Vdbe *v;
|
||||
va_list ap;
|
||||
int iThis;
|
||||
va_start(ap, zFmt);
|
||||
@ -1661,9 +1661,9 @@ static void releaseMemArray(Mem *p, int N){
|
||||
*/
|
||||
testcase( p->flags & MEM_Agg );
|
||||
testcase( p->flags & MEM_Dyn );
|
||||
testcase( p->flags & MEM_Frame );
|
||||
testcase( p->xDel==sqlite3VdbeFrameMemDel );
|
||||
testcase( p->flags & MEM_RowSet );
|
||||
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
|
||||
if( p->flags&(MEM_Agg|MEM_Dyn) ){
|
||||
sqlite3VdbeMemRelease(p);
|
||||
}else if( p->szMalloc ){
|
||||
sqlite3DbFreeNN(db, p->zMalloc);
|
||||
@ -1675,6 +1675,35 @@ static void releaseMemArray(Mem *p, int N){
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is
|
||||
** and false if something is wrong.
|
||||
**
|
||||
** This routine is intended for use inside of assert() statements only.
|
||||
*/
|
||||
int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){
|
||||
if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** This is a destructor on a Mem object (which is really an sqlite3_value)
|
||||
** that deletes the Frame object that is attached to it as a blob.
|
||||
**
|
||||
** This routine does not delete the Frame right away. It merely adds the
|
||||
** frame to a list of frames to be deleted when the Vdbe halts.
|
||||
*/
|
||||
void sqlite3VdbeFrameMemDel(void *pArg){
|
||||
VdbeFrame *pFrame = (VdbeFrame*)pArg;
|
||||
assert( sqlite3VdbeFrameIsValid(pFrame) );
|
||||
pFrame->pParent = pFrame->v->pDelFrame;
|
||||
pFrame->v->pDelFrame = pFrame;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
|
||||
** allocated by the OP_Program opcode in sqlite3VdbeExec().
|
||||
@ -1683,6 +1712,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){
|
||||
int i;
|
||||
Mem *aMem = VdbeFrameMem(p);
|
||||
VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
|
||||
assert( sqlite3VdbeFrameIsValid(p) );
|
||||
for(i=0; i<p->nChildCsr; i++){
|
||||
sqlite3VdbeFreeCursor(p->v, apCsr[i]);
|
||||
}
|
||||
@ -3961,7 +3991,7 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
|
||||
f1 = pMem1->flags;
|
||||
f2 = pMem2->flags;
|
||||
combined_flags = f1|f2;
|
||||
assert( (combined_flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) );
|
||||
|
||||
/* If one value is NULL, it is less than the other. If both values
|
||||
** are NULL, return 0.
|
||||
|
@ -42,8 +42,7 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
|
||||
|
||||
if( p->flags & MEM_Null ){
|
||||
/* Cannot be both MEM_Null and some other type */
|
||||
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
|
||||
|MEM_RowSet|MEM_Frame|MEM_Agg))==0 );
|
||||
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
|
||||
|
||||
/* If MEM_Null is set, then either the value is a pure NULL (the usual
|
||||
** case) or it is a pointer set using sqlite3_bind_pointer() or
|
||||
@ -156,7 +155,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
int rc;
|
||||
#endif
|
||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
|
||||
|| desiredEnc==SQLITE_UTF16BE );
|
||||
if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
|
||||
@ -189,7 +188,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
||||
*/
|
||||
SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
|
||||
assert( sqlite3VdbeCheckMemInvariants(pMem) );
|
||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
testcase( pMem->db==0 );
|
||||
|
||||
/* If the bPreserve flag is set to true, then the memory cell must already
|
||||
@ -277,7 +276,7 @@ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
|
||||
*/
|
||||
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
|
||||
if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
|
||||
if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
|
||||
@ -302,7 +301,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
||||
int nByte;
|
||||
assert( pMem->flags & MEM_Zero );
|
||||
assert( pMem->flags&MEM_Blob );
|
||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
|
||||
/* Set nByte to the number of bytes required to store the expanded blob. */
|
||||
@ -357,7 +356,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
|
||||
assert( !(fg&MEM_Zero) );
|
||||
assert( !(fg&(MEM_Str|MEM_Blob)) );
|
||||
assert( fg&(MEM_Int|MEM_Real) );
|
||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
||||
|
||||
|
||||
@ -462,15 +461,8 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
|
||||
testcase( p->flags & MEM_Dyn );
|
||||
}
|
||||
if( p->flags&MEM_Dyn ){
|
||||
assert( (p->flags&MEM_RowSet)==0 );
|
||||
assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
|
||||
p->xDel((void *)p->z);
|
||||
}else if( p->flags&MEM_RowSet ){
|
||||
sqlite3RowSetClear(p->u.pRowSet);
|
||||
}else if( p->flags&MEM_Frame ){
|
||||
VdbeFrame *pFrame = p->u.pFrame;
|
||||
pFrame->pParent = pFrame->v->pDelFrame;
|
||||
pFrame->v->pDelFrame = pFrame;
|
||||
}
|
||||
p->flags = MEM_Null;
|
||||
}
|
||||
@ -618,7 +610,7 @@ int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
|
||||
void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
||||
i64 ix;
|
||||
assert( pMem->flags & MEM_Real );
|
||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
||||
|
||||
@ -645,7 +637,7 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
||||
*/
|
||||
int sqlite3VdbeMemIntegerify(Mem *pMem){
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
||||
|
||||
pMem->u.i = sqlite3VdbeIntValue(pMem);
|
||||
@ -863,26 +855,36 @@ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Return true if the Mem holds a RowSet object. This routine is intended
|
||||
** for use inside of assert() statements.
|
||||
*/
|
||||
int sqlite3VdbeMemIsRowSet(const Mem *pMem){
|
||||
return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn)
|
||||
&& pMem->xDel==sqlite3RowSetDelete;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Delete any previous value and set the value of pMem to be an
|
||||
** empty boolean index.
|
||||
**
|
||||
** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation
|
||||
** error occurs.
|
||||
*/
|
||||
void sqlite3VdbeMemSetRowSet(Mem *pMem){
|
||||
int sqlite3VdbeMemSetRowSet(Mem *pMem){
|
||||
sqlite3 *db = pMem->db;
|
||||
RowSet *p;
|
||||
assert( db!=0 );
|
||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
sqlite3VdbeMemRelease(pMem);
|
||||
pMem->zMalloc = sqlite3DbMallocRawNN(db, 64);
|
||||
if( db->mallocFailed ){
|
||||
pMem->flags = MEM_Null;
|
||||
pMem->szMalloc = 0;
|
||||
}else{
|
||||
assert( pMem->zMalloc );
|
||||
pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc);
|
||||
pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc);
|
||||
assert( pMem->u.pRowSet!=0 );
|
||||
pMem->flags = MEM_RowSet;
|
||||
}
|
||||
p = sqlite3RowSetInit(db);
|
||||
if( p==0 ) return SQLITE_NOMEM;
|
||||
pMem->z = (char*)p;
|
||||
pMem->flags = MEM_Blob|MEM_Dyn;
|
||||
pMem->xDel = sqlite3RowSetDelete;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -950,7 +952,7 @@ static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){
|
||||
sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
|
||||
}
|
||||
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
||||
assert( (pFrom->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pFrom) );
|
||||
assert( pTo->db==pFrom->db );
|
||||
if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
|
||||
memcpy(pTo, pFrom, MEMCELLSIZE);
|
||||
@ -968,7 +970,7 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
||||
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( (pFrom->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pFrom) );
|
||||
if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
|
||||
memcpy(pTo, pFrom, MEMCELLSIZE);
|
||||
pTo->flags &= ~MEM_Dyn;
|
||||
@ -1026,7 +1028,7 @@ int sqlite3VdbeMemSetStr(
|
||||
u16 flags = 0; /* New value for pMem->flags */
|
||||
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
|
||||
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
|
||||
if( !z ){
|
||||
@ -1148,7 +1150,7 @@ int sqlite3VdbeMemFromBtree(
|
||||
|
||||
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
|
||||
** that both the BtShared and database handle mutexes are held. */
|
||||
assert( (pMem->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pMem) );
|
||||
zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
|
||||
assert( zData!=0 );
|
||||
|
||||
@ -1172,7 +1174,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
|
||||
assert( pVal!=0 );
|
||||
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
|
||||
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
|
||||
assert( (pVal->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pVal) );
|
||||
assert( (pVal->flags & (MEM_Null))==0 );
|
||||
if( pVal->flags & (MEM_Blob|MEM_Str) ){
|
||||
if( ExpandBlob(pVal) ) return 0;
|
||||
@ -1215,7 +1217,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
|
||||
if( !pVal ) return 0;
|
||||
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
|
||||
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
|
||||
assert( (pVal->flags & MEM_RowSet)==0 );
|
||||
assert( !sqlite3VdbeMemIsRowSet(pVal) );
|
||||
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
|
||||
assert( sqlite3VdbeMemConsistentDualRep(pVal) );
|
||||
return pVal->z;
|
||||
|
@ -2107,7 +2107,11 @@ static int vdbeMergeEngineInit(
|
||||
){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int i; /* For looping over PmaReader objects */
|
||||
int nTree = pMerger->nTree;
|
||||
int nTree; /* Number of subtrees to merge */
|
||||
|
||||
/* Failure to allocate the merge would have been detected prior to
|
||||
** invoking this routine */
|
||||
assert( pMerger!=0 );
|
||||
|
||||
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
|
||||
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
|
||||
@ -2116,6 +2120,7 @@ static int vdbeMergeEngineInit(
|
||||
assert( pMerger->pTask==0 );
|
||||
pMerger->pTask = pTask;
|
||||
|
||||
nTree = pMerger->nTree;
|
||||
for(i=0; i<nTree; i++){
|
||||
if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){
|
||||
/* PmaReaders should be normally initialized in order, as if they are
|
||||
|
27
src/wal.c
27
src/wal.c
@ -258,6 +258,18 @@ int sqlite3WalTrace = 0;
|
||||
# define WALTRACE(X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
|
||||
** places. The following macros try to make this explicit.
|
||||
*/
|
||||
#if GCC_VESRION>=5004000
|
||||
# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
|
||||
# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
|
||||
#else
|
||||
# define AtomicLoad(PTR) (*(PTR))
|
||||
# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The maximum (and only) versions of the wal and wal-index formats
|
||||
** that may be interpreted by this version of SQLite.
|
||||
@ -2555,7 +2567,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
|
||||
}
|
||||
#endif
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
u32 thisMark = pInfo->aReadMark[i];
|
||||
u32 thisMark = AtomicLoad(pInfo->aReadMark+i);
|
||||
if( mxReadMark<=thisMark && thisMark<=mxFrame ){
|
||||
assert( thisMark!=READMARK_NOT_USED );
|
||||
mxReadMark = thisMark;
|
||||
@ -2568,7 +2580,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
if( rc==SQLITE_OK ){
|
||||
mxReadMark = pInfo->aReadMark[i] = mxFrame;
|
||||
mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
|
||||
mxI = i;
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
break;
|
||||
@ -2620,9 +2632,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
|
||||
** we can guarantee that the checkpointer that set nBackfill could not
|
||||
** see any pages past pWal->hdr.mxFrame, this problem does not come up.
|
||||
*/
|
||||
pWal->minFrame = pInfo->nBackfill+1;
|
||||
pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1;
|
||||
walShmBarrier(pWal);
|
||||
if( pInfo->aReadMark[mxI]!=mxReadMark
|
||||
if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark
|
||||
|| memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
|
||||
){
|
||||
walUnlockShared(pWal, WAL_READ_LOCK(mxI));
|
||||
@ -2783,7 +2795,7 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
|
||||
/* Check that the wal file has not been wrapped. Assuming that it has
|
||||
** not, also check that no checkpointer has attempted to checkpoint any
|
||||
** frames beyond pSnapshot->mxFrame. If either of these conditions are
|
||||
** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr
|
||||
** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
|
||||
** with *pSnapshot and set *pChanged as appropriate for opening the
|
||||
** snapshot. */
|
||||
if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
|
||||
@ -2793,11 +2805,12 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
|
||||
memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
|
||||
*pChanged = bChanged;
|
||||
}else{
|
||||
rc = SQLITE_BUSY_SNAPSHOT;
|
||||
rc = SQLITE_ERROR_SNAPSHOT;
|
||||
}
|
||||
|
||||
/* Release the shared CKPT lock obtained above. */
|
||||
walUnlockShared(pWal, WAL_CKPT_LOCK);
|
||||
pWal->minFrame = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -3789,7 +3802,7 @@ int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){
|
||||
if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
|
||||
|| pNew->mxFrame<walCkptInfo(pWal)->nBackfillAttempted
|
||||
){
|
||||
rc = SQLITE_BUSY_SNAPSHOT;
|
||||
rc = SQLITE_ERROR_SNAPSHOT;
|
||||
walUnlockShared(pWal, WAL_CKPT_LOCK);
|
||||
}
|
||||
}
|
||||
|
@ -340,6 +340,7 @@ static int isLikeOrGlob(
|
||||
** If the expression matches none of the patterns above, return 0.
|
||||
*/
|
||||
static int isAuxiliaryVtabOperator(
|
||||
sqlite3 *db, /* Parsing context */
|
||||
Expr *pExpr, /* Test this expression */
|
||||
unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */
|
||||
Expr **ppLeft, /* Column expression to left of MATCH/op2 */
|
||||
@ -363,16 +364,54 @@ static int isAuxiliaryVtabOperator(
|
||||
if( pList==0 || pList->nExpr!=2 ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a
|
||||
** virtual table on their second argument, which is the same as
|
||||
** the left-hand side operand in their in-fix form.
|
||||
**
|
||||
** vtab_column MATCH expression
|
||||
** MATCH(expression,vtab_column)
|
||||
*/
|
||||
pCol = pList->a[1].pExpr;
|
||||
if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
|
||||
return 0;
|
||||
if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
|
||||
for(i=0; i<ArraySize(aOp); i++){
|
||||
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
|
||||
*peOp2 = aOp[i].eOp2;
|
||||
*ppRight = pList->a[0].pExpr;
|
||||
*ppLeft = pCol;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=0; i<ArraySize(aOp); i++){
|
||||
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
|
||||
*peOp2 = aOp[i].eOp2;
|
||||
*ppRight = pList->a[0].pExpr;
|
||||
*ppLeft = pCol;
|
||||
return 1;
|
||||
|
||||
/* We can also match against the first column of overloaded
|
||||
** functions where xFindFunction returns a value of at least
|
||||
** SQLITE_INDEX_CONSTRAINT_FUNCTION.
|
||||
**
|
||||
** OVERLOADED(vtab_column,expression)
|
||||
**
|
||||
** Historically, xFindFunction expected to see lower-case function
|
||||
** names. But for this use case, xFindFunction is expected to deal
|
||||
** with function names in an arbitrary case.
|
||||
*/
|
||||
pCol = pList->a[0].pExpr;
|
||||
if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
|
||||
sqlite3_vtab *pVtab;
|
||||
sqlite3_module *pMod;
|
||||
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
|
||||
void *pNotUsed;
|
||||
pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
|
||||
assert( pVtab!=0 );
|
||||
assert( pVtab->pModule!=0 );
|
||||
pMod = (sqlite3_module *)pVtab->pModule;
|
||||
if( pMod->xFindFunction!=0 ){
|
||||
i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
|
||||
if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
|
||||
*peOp2 = i;
|
||||
*ppRight = pList->a[1].pExpr;
|
||||
*ppLeft = pCol;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
|
||||
@ -820,7 +859,7 @@ static void exprAnalyzeOrTerm(
|
||||
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
|
||||
testcase( idxNew==0 );
|
||||
exprAnalyze(pSrc, pWC, idxNew);
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
/* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */
|
||||
markTermAsChild(pWC, idxNew, idxTerm);
|
||||
}else{
|
||||
sqlite3ExprListDelete(db, pList);
|
||||
@ -1237,7 +1276,7 @@ static void exprAnalyze(
|
||||
*/
|
||||
if( pWC->op==TK_AND ){
|
||||
Expr *pRight = 0, *pLeft = 0;
|
||||
int res = isAuxiliaryVtabOperator(pExpr, &eOp2, &pLeft, &pRight);
|
||||
int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight);
|
||||
while( res-- > 0 ){
|
||||
int idxNew;
|
||||
WhereTerm *pNewTerm;
|
||||
|
@ -26,6 +26,15 @@ if {[llength [info command client_step]]==0 || [sqlite3 -has-codec]} {
|
||||
return
|
||||
}
|
||||
|
||||
# This test does not work on older PPC Macs due to problems in the
|
||||
# pthreads library. So skip it.
|
||||
#
|
||||
if {$tcl_platform(machine)=="Power Macintosh" &&
|
||||
$tcl_platform(byteOrder)=="bigEndian"} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# The sample server implementation does not work right when memory
|
||||
# management is enabled.
|
||||
#
|
||||
|
@ -258,7 +258,7 @@ foreach {tn tcl} {
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that SQLITE_BUSY_SNAPSHOT is returned if the specified snapshot
|
||||
# Check that SQLITE_ERROR_SNAPSHOT is returned if the specified snapshot
|
||||
# no longer exists because the wal file has been checkpointed.
|
||||
#
|
||||
# 1. Reading a snapshot from the middle of a wal file is not possible
|
||||
@ -296,7 +296,7 @@ foreach {tn tcl} {
|
||||
BEGIN;
|
||||
}
|
||||
list [catch {snapshot_open db main $snapshot} msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
do_test $tn.4.1.4 {
|
||||
snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
@ -327,7 +327,7 @@ foreach {tn tcl} {
|
||||
BEGIN;
|
||||
}
|
||||
list [catch {snapshot_open db main $snapshot} msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
do_test $tn.4.2.4 {
|
||||
snapshot_free $snapshot
|
||||
} {}
|
||||
|
@ -110,7 +110,7 @@ do_test 2.2 {
|
||||
execsql {SELECT * FROM sqlite_master}
|
||||
execsql BEGIN
|
||||
list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
|
||||
do_test 2.3 {
|
||||
execsql COMMIT
|
||||
@ -134,7 +134,7 @@ do_test 2.5 {
|
||||
sqlite3_snapshot_recover db main
|
||||
execsql BEGIN
|
||||
list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that calling sqlite3_snapshot_recover() does not confuse the
|
||||
@ -234,7 +234,7 @@ do_test 5.4 {
|
||||
execsql { INSERT INTO t2 VALUES('jkl') }
|
||||
execsql BEGIN db2
|
||||
list [catch { sqlite3_snapshot_open_blob db2 main $snap } msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
|
||||
|
||||
finish_test
|
||||
|
@ -94,7 +94,7 @@ do_test 1.7 {
|
||||
do_test 1.8 {
|
||||
execsql BEGIN db3
|
||||
list [catch { sqlite3_snapshot_open_blob db3 main $snap } msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
|
||||
finish_test
|
||||
|
||||
|
75
test/snapshot4.test
Normal file
75
test/snapshot4.test
Normal file
@ -0,0 +1,75 @@
|
||||
# 2018 August 28
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The focus
|
||||
# of this file is the sqlite3_snapshot_xxx() APIs.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !snapshot {finish_test; return}
|
||||
set testprefix snapshot4
|
||||
|
||||
# This test does not work with the inmemory_journal permutation. The reason
|
||||
# is that each connection opened as part of this permutation executes
|
||||
# "PRAGMA journal_mode=memory", which fails if the database is in wal mode
|
||||
# and there are one or more existing connections.
|
||||
if {[permutation]=="inmemory_journal"} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
sqlite3 db2 test.db
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA cache_size = 10;
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, randomblob(400));
|
||||
PRAGMA journal_mode = wal;
|
||||
WITH s(i) AS (
|
||||
SELECT 2 UNION ALL SELECT i+1 FROM s WHERE i<100
|
||||
)
|
||||
INSERT INTO t1 SELECT i, randomblob(400) FROM s;
|
||||
} {wal}
|
||||
|
||||
do_test 1.1 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {100}
|
||||
|
||||
do_test 1.2 {
|
||||
db2 eval {
|
||||
SELECT count(*) FROM t1;
|
||||
CREATE TABLE t2(x);
|
||||
}
|
||||
} {100}
|
||||
|
||||
do_test 1.3 {
|
||||
set ::snap [sqlite3_snapshot_get_blob db main]
|
||||
db2 eval { PRAGMA wal_checkpoint }
|
||||
} {0 54 52}
|
||||
|
||||
do_test 1.4 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
SELECT * FROM sqlite_master;
|
||||
BEGIN;
|
||||
}
|
||||
sqlite3_snapshot_open_blob db main $::snap
|
||||
execsql {
|
||||
SELECT count(*) FROM t1
|
||||
}
|
||||
} {100}
|
||||
|
||||
|
||||
finish_test
|
||||
|
@ -47,7 +47,7 @@ do_faultsim_test 1.0 -prep {
|
||||
} -test {
|
||||
db2 eval BEGIN
|
||||
if {[catch { sqlite3_snapshot_open db2 main $::snapshot } msg]} {
|
||||
if {$msg != "SQLITE_BUSY_SNAPSHOT" && $msg != "SQLITE_BUSY"} {
|
||||
if {$msg != "SQLITE_ERROR_SNAPSHOT" && $msg != "SQLITE_BUSY"} {
|
||||
error "error is $msg"
|
||||
}
|
||||
} else {
|
||||
@ -98,7 +98,7 @@ do_faultsim_test 2.0 -prep {
|
||||
|
||||
db eval BEGIN
|
||||
if {[catch { sqlite3_snapshot_open db main $::snapshot } msg]} {
|
||||
if {$msg != "SQLITE_BUSY_SNAPSHOT" && $msg != "SQLITE_BUSY"} {
|
||||
if {$msg != "SQLITE_ERROR_SNAPSHOT" && $msg != "SQLITE_BUSY"} {
|
||||
error "error is $msg"
|
||||
}
|
||||
} else {
|
||||
|
@ -75,7 +75,7 @@ do_execsql_test 1.6 {
|
||||
|
||||
do_test 1.7 {
|
||||
list [catch { sqlite3_snapshot_open db main $::snap1 } msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
|
||||
do_execsql_test 1.8 {
|
||||
SELECT * FROM t1
|
||||
@ -84,7 +84,7 @@ do_execsql_test 1.8 {
|
||||
do_test 1.9 {
|
||||
execsql { COMMIT ; BEGIN }
|
||||
list [catch { sqlite3_snapshot_open db main $::snap1 } msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
|
||||
do_test 1.10 {
|
||||
execsql { COMMIT }
|
||||
@ -113,7 +113,7 @@ do_test 1.12 {
|
||||
|
||||
do_test 1.13 {
|
||||
list [catch { sqlite3_snapshot_open db main $::snap3 } msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
do_test 1.14 {
|
||||
execsql { SELECT * FROM t1 }
|
||||
} {4 5 6 7 8 9 10 11 12 13 14 15}
|
||||
@ -127,7 +127,7 @@ do_execsql_test 1.15 {
|
||||
} {7 8 9 10 11 12 13 14 15}
|
||||
do_test 1.16 {
|
||||
list [catch { sqlite3_snapshot_open db main $::snap4 } msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
} {1 SQLITE_ERROR_SNAPSHOT}
|
||||
do_execsql_test 1.17 { COMMIT }
|
||||
|
||||
sqlite3_snapshot_free $::snap1
|
||||
|
@ -691,10 +691,13 @@ do_test view-25.1 {
|
||||
db eval {DROP VIEW x1;}
|
||||
set log
|
||||
} {}
|
||||
|
||||
set res [list {SQLITE_DELETE sqlite_stat1 {} main {} {}}]
|
||||
ifcapable stat4 { lappend res {SQLITE_DELETE sqlite_stat4 {} main {} {}} }
|
||||
do_test view-25.2 {
|
||||
set log ""
|
||||
db eval {DROP TABLE t25;}
|
||||
set log
|
||||
} {{SQLITE_DELETE sqlite_stat1 {} main {} {}}}
|
||||
} $res
|
||||
|
||||
finish_test
|
||||
|
@ -99,6 +99,7 @@ foreach hdr {
|
||||
fts3Int.h
|
||||
fts3_hash.h
|
||||
fts3_tokenizer.h
|
||||
geopoly.c
|
||||
hash.h
|
||||
hwtime.h
|
||||
keywordhash.h
|
||||
@ -392,6 +393,7 @@ foreach file {
|
||||
fts3_unicode.c
|
||||
fts3_unicode2.c
|
||||
|
||||
json1.c
|
||||
rtree.c
|
||||
icu.c
|
||||
fts3_icu.c
|
||||
@ -399,7 +401,6 @@ foreach file {
|
||||
dbstat.c
|
||||
dbpage.c
|
||||
sqlite3session.c
|
||||
json1.c
|
||||
fts5.c
|
||||
stmt.c
|
||||
} {
|
||||
|
Loading…
Reference in New Issue
Block a user