Merge latest trunk with this branch.
FossilOrigin-Name: e051e8f21b909c5e89a7203eef6501fecd64f82a634c4e10398b5ef7d716eb37
This commit is contained in:
@@ -11252,7 +11252,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${use_debug}" = "yes" ; then
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
|
||||
else
|
||||
TARGET_DEBUG="-DNDEBUG"
|
||||
fi
|
||||
@@ -11356,7 +11356,7 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5
|
||||
$as_echo_n "checking whether to support MEMSYS5... " >&6; }
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MEMSYS5"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
@@ -11373,7 +11373,7 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5
|
||||
$as_echo_n "checking whether to support MEMSYS3... " >&6; }
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MEMSYS3"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
@@ -11391,7 +11391,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts3}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3"
|
||||
fi
|
||||
# Check whether --enable-fts4 was given.
|
||||
if test "${enable_fts4+set}" = set; then :
|
||||
@@ -11401,7 +11401,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts4}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
|
||||
$as_echo_n "checking for library containing log... " >&6; }
|
||||
if ${ac_cv_search_log+:} false; then :
|
||||
@@ -11467,7 +11467,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts5}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
|
||||
$as_echo_n "checking for library containing log... " >&6; }
|
||||
if ${ac_cv_search_log+:} false; then :
|
||||
@@ -11536,7 +11536,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_json1}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -11549,7 +11549,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_rtree}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -11562,8 +11562,8 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_session}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
fi
|
||||
|
||||
#########
|
||||
|
||||
+10
-10
@@ -560,7 +560,7 @@ AC_SEARCH_LIBS(fdatasync, [rt])
|
||||
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]),
|
||||
[use_debug=$enableval],[use_debug=no])
|
||||
if test "${use_debug}" = "yes" ; then
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
|
||||
else
|
||||
TARGET_DEBUG="-DNDEBUG"
|
||||
fi
|
||||
@@ -596,7 +596,7 @@ AC_ARG_ENABLE(memsys5,
|
||||
[enable_memsys5=yes],[enable_memsys5=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS5])
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MEMSYS5"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
@@ -606,7 +606,7 @@ AC_ARG_ENABLE(memsys3,
|
||||
[enable_memsys3=yes],[enable_memsys3=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS3])
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MEMSYS3"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
@@ -618,20 +618,20 @@ AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
|
||||
[Enable the FTS3 extension]),
|
||||
[enable_fts3=yes],[enable_fts3=no])
|
||||
if test "${enable_fts3}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3"
|
||||
fi
|
||||
AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
|
||||
[Enable the FTS4 extension]),
|
||||
[enable_fts4=yes],[enable_fts4=no])
|
||||
if test "${enable_fts4}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4"
|
||||
AC_SEARCH_LIBS([log],[m])
|
||||
fi
|
||||
AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
|
||||
[Enable the FTS5 extension]),
|
||||
[enable_fts5=yes],[enable_fts5=no])
|
||||
if test "${enable_fts5}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5"
|
||||
AC_SEARCH_LIBS([log],[m])
|
||||
fi
|
||||
|
||||
@@ -641,7 +641,7 @@ AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],
|
||||
[Enable the JSON1 extension]),
|
||||
[enable_json1=yes],[enable_json1=no])
|
||||
if test "${enable_json1}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -650,7 +650,7 @@ AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
|
||||
[Enable the RTREE extension]),
|
||||
[enable_rtree=yes],[enable_rtree=no])
|
||||
if test "${enable_rtree}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -659,8 +659,8 @@ AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session],
|
||||
[Enable the SESSION extension]),
|
||||
[enable_session=yes],[enable_session=no])
|
||||
if test "${enable_session}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
fi
|
||||
|
||||
#########
|
||||
|
||||
+3
-3
@@ -446,9 +446,9 @@ int sqlite3Fts5IndexBeginWrite(
|
||||
|
||||
/*
|
||||
** Flush any data stored in the in-memory hash tables to the database.
|
||||
** If the bCommit flag is true, also close any open blob handles.
|
||||
** Also close any open blob handles.
|
||||
*/
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit);
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p);
|
||||
|
||||
/*
|
||||
** Discard any data stored in the in-memory hash tables. Do not write it
|
||||
@@ -618,7 +618,7 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
|
||||
int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
|
||||
int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
|
||||
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit);
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p);
|
||||
int sqlite3Fts5StorageRollback(Fts5Storage *p);
|
||||
|
||||
int sqlite3Fts5StorageConfigValue(
|
||||
|
||||
@@ -628,7 +628,6 @@ static void fts5CloseReader(Fts5Index *p){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Retrieve a record from the %_data table.
|
||||
**
|
||||
@@ -5131,10 +5130,10 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
|
||||
/*
|
||||
** Commit data to disk.
|
||||
*/
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p){
|
||||
assert( p->rc==SQLITE_OK );
|
||||
fts5IndexFlush(p);
|
||||
if( bCommit ) fts5CloseReader(p);
|
||||
fts5CloseReader(p);
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
|
||||
@@ -1579,7 +1579,7 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
|
||||
fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
|
||||
pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
|
||||
fts5TripCursors(pTab);
|
||||
rc = sqlite3Fts5StorageSync(pTab->pStorage, 1);
|
||||
rc = sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
pTab->pConfig->pzErrmsg = 0;
|
||||
return rc;
|
||||
}
|
||||
@@ -2390,7 +2390,7 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2403,7 +2403,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -218,7 +218,7 @@ static void fts5StorageRenameOne(
|
||||
|
||||
int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
|
||||
Fts5Config *pConfig = pStorage->pConfig;
|
||||
int rc = sqlite3Fts5StorageSync(pStorage, 1);
|
||||
int rc = sqlite3Fts5StorageSync(pStorage);
|
||||
|
||||
fts5StorageRenameOne(pConfig, &rc, "data", zName);
|
||||
fts5StorageRenameOne(pConfig, &rc, "idx", zName);
|
||||
@@ -1081,15 +1081,15 @@ int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
|
||||
/*
|
||||
** Flush any data currently held in-memory to disk.
|
||||
*/
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p){
|
||||
int rc = SQLITE_OK;
|
||||
i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
|
||||
if( p->bTotalsValid ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
if( bCommit ) p->bTotalsValid = 0;
|
||||
p->bTotalsValid = 0;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexSync(p->pIndex, bCommit);
|
||||
rc = sqlite3Fts5IndexSync(p->pIndex);
|
||||
}
|
||||
sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
|
||||
return rc;
|
||||
|
||||
@@ -561,6 +561,22 @@ do_test 20.1 {
|
||||
execsql { SELECT rowid FROM tmp WHERE tmp MATCH 'y' }
|
||||
} $::ids
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Test that a DROP TABLE may be executed within a transaction that
|
||||
# writes to an FTS5 table.
|
||||
#
|
||||
do_execsql_test 21.0 {
|
||||
CREATE TEMP TABLE t8(a, b);
|
||||
CREATE VIRTUAL TABLE ft USING fts5(x, detail=%DETAIL%);
|
||||
}
|
||||
|
||||
do_execsql_test 21.1 {
|
||||
BEGIN;
|
||||
INSERT INTO ft VALUES('a b c');
|
||||
DROP TABLE t8;
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+33
-27
@@ -727,13 +727,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
int iThis;
|
||||
int x;
|
||||
JsonNode *pNode;
|
||||
while( safe_isspace(pParse->zJson[i]) ){ i++; }
|
||||
if( (c = pParse->zJson[i])=='{' ){
|
||||
const char *z = pParse->zJson;
|
||||
while( safe_isspace(z[i]) ){ i++; }
|
||||
if( (c = z[i])=='{' ){
|
||||
/* Parse object */
|
||||
iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
|
||||
if( iThis<0 ) return -1;
|
||||
for(j=i+1;;j++){
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
while( safe_isspace(z[j]) ){ j++; }
|
||||
x = jsonParseValue(pParse, j);
|
||||
if( x<0 ){
|
||||
if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
|
||||
@@ -744,14 +745,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
if( pNode->eType!=JSON_STRING ) return -1;
|
||||
pNode->jnFlags |= JNODE_LABEL;
|
||||
j = x;
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
if( pParse->zJson[j]!=':' ) return -1;
|
||||
while( safe_isspace(z[j]) ){ j++; }
|
||||
if( z[j]!=':' ) return -1;
|
||||
j++;
|
||||
x = jsonParseValue(pParse, j);
|
||||
if( x<0 ) return -1;
|
||||
j = x;
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
c = pParse->zJson[j];
|
||||
while( safe_isspace(z[j]) ){ j++; }
|
||||
c = z[j];
|
||||
if( c==',' ) continue;
|
||||
if( c!='}' ) return -1;
|
||||
break;
|
||||
@@ -763,15 +764,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
|
||||
if( iThis<0 ) return -1;
|
||||
for(j=i+1;;j++){
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
while( safe_isspace(z[j]) ){ j++; }
|
||||
x = jsonParseValue(pParse, j);
|
||||
if( x<0 ){
|
||||
if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
|
||||
return -1;
|
||||
}
|
||||
j = x;
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
c = pParse->zJson[j];
|
||||
while( safe_isspace(z[j]) ){ j++; }
|
||||
c = z[j];
|
||||
if( c==',' ) continue;
|
||||
if( c!=']' ) return -1;
|
||||
break;
|
||||
@@ -783,13 +784,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
u8 jnFlags = 0;
|
||||
j = i+1;
|
||||
for(;;){
|
||||
c = pParse->zJson[j];
|
||||
c = z[j];
|
||||
if( c==0 ) return -1;
|
||||
if( c=='\\' ){
|
||||
c = pParse->zJson[++j];
|
||||
c = z[++j];
|
||||
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
|
||||
|| c=='n' || c=='r' || c=='t'
|
||||
|| (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){
|
||||
|| (c=='u' && jsonIs4Hex(z+j+1)) ){
|
||||
jnFlags = JNODE_ESCAPE;
|
||||
}else{
|
||||
return -1;
|
||||
@@ -799,55 +800,60 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
}
|
||||
j++;
|
||||
}
|
||||
jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
|
||||
jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
|
||||
if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
|
||||
return j+1;
|
||||
}else if( c=='n'
|
||||
&& strncmp(pParse->zJson+i,"null",4)==0
|
||||
&& !safe_isalnum(pParse->zJson[i+4]) ){
|
||||
&& strncmp(z+i,"null",4)==0
|
||||
&& !safe_isalnum(z[i+4]) ){
|
||||
jsonParseAddNode(pParse, JSON_NULL, 0, 0);
|
||||
return i+4;
|
||||
}else if( c=='t'
|
||||
&& strncmp(pParse->zJson+i,"true",4)==0
|
||||
&& !safe_isalnum(pParse->zJson[i+4]) ){
|
||||
&& strncmp(z+i,"true",4)==0
|
||||
&& !safe_isalnum(z[i+4]) ){
|
||||
jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
|
||||
return i+4;
|
||||
}else if( c=='f'
|
||||
&& strncmp(pParse->zJson+i,"false",5)==0
|
||||
&& !safe_isalnum(pParse->zJson[i+5]) ){
|
||||
&& strncmp(z+i,"false",5)==0
|
||||
&& !safe_isalnum(z[i+5]) ){
|
||||
jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
|
||||
return i+5;
|
||||
}else if( c=='-' || (c>='0' && c<='9') ){
|
||||
/* Parse number */
|
||||
u8 seenDP = 0;
|
||||
u8 seenE = 0;
|
||||
assert( '-' < '0' );
|
||||
if( c<='0' ){
|
||||
j = c=='-' ? i+1 : i;
|
||||
if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
|
||||
}
|
||||
j = i+1;
|
||||
for(;; j++){
|
||||
c = pParse->zJson[j];
|
||||
c = z[j];
|
||||
if( c>='0' && c<='9' ) continue;
|
||||
if( c=='.' ){
|
||||
if( pParse->zJson[j-1]=='-' ) return -1;
|
||||
if( z[j-1]=='-' ) return -1;
|
||||
if( seenDP ) return -1;
|
||||
seenDP = 1;
|
||||
continue;
|
||||
}
|
||||
if( c=='e' || c=='E' ){
|
||||
if( pParse->zJson[j-1]<'0' ) return -1;
|
||||
if( z[j-1]<'0' ) return -1;
|
||||
if( seenE ) return -1;
|
||||
seenDP = seenE = 1;
|
||||
c = pParse->zJson[j+1];
|
||||
c = z[j+1];
|
||||
if( c=='+' || c=='-' ){
|
||||
j++;
|
||||
c = pParse->zJson[j+1];
|
||||
c = z[j+1];
|
||||
}
|
||||
if( c<'0' || c>'9' ) return -1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( pParse->zJson[j-1]<'0' ) return -1;
|
||||
if( z[j-1]<'0' ) return -1;
|
||||
jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
|
||||
j - i, &pParse->zJson[i]);
|
||||
j - i, &z[i]);
|
||||
return j;
|
||||
}else if( c=='}' ){
|
||||
return -2; /* End of {...} */
|
||||
|
||||
+25
-2
@@ -3198,12 +3198,35 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
|
||||
, pRtree->zDb, pRtree->zName, zNewName
|
||||
);
|
||||
if( zSql ){
|
||||
nodeBlobReset(pRtree);
|
||||
rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** The xSavepoint method.
|
||||
**
|
||||
** This module does not need to do anything to support savepoints. However,
|
||||
** it uses this hook to close any open blob handle. This is done because a
|
||||
** DROP TABLE command - which fortunately always opens a savepoint - cannot
|
||||
** succeed if there are any open blob handles. i.e. if the blob handle were
|
||||
** not closed here, the following would fail:
|
||||
**
|
||||
** BEGIN;
|
||||
** INSERT INTO rtree...
|
||||
** DROP TABLE <tablename>; -- Would fail with SQLITE_LOCKED
|
||||
** COMMIT;
|
||||
*/
|
||||
static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
Rtree *pRtree = (Rtree *)pVtab;
|
||||
int iwt = pRtree->inWrTrans;
|
||||
pRtree->inWrTrans = 0;
|
||||
nodeBlobReset(pRtree);
|
||||
pRtree->inWrTrans = iwt;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function populates the pRtree->nRowEst variable with an estimate
|
||||
@@ -3250,7 +3273,7 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
|
||||
}
|
||||
|
||||
static sqlite3_module rtreeModule = {
|
||||
0, /* iVersion */
|
||||
2, /* iVersion */
|
||||
rtreeCreate, /* xCreate - create a table */
|
||||
rtreeConnect, /* xConnect - connect to an existing table */
|
||||
rtreeBestIndex, /* xBestIndex - Determine search strategy */
|
||||
@@ -3270,7 +3293,7 @@ static sqlite3_module rtreeModule = {
|
||||
rtreeEndTransaction, /* xRollback - rollback transaction */
|
||||
0, /* xFindFunction - function overloading */
|
||||
rtreeRename, /* xRename - rename the table */
|
||||
0, /* xSavepoint */
|
||||
rtreeSavepoint, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
};
|
||||
|
||||
@@ -39,6 +39,8 @@ set testprefix rtree1
|
||||
# inserted. Also that if a non-numeric is inserted into one
|
||||
# of the min/max dimension columns, it is converted to the
|
||||
# required type before being inserted.
|
||||
# rtree-15.*: Check that DROP TABLE works within a transaction that
|
||||
# writes to an r-tree table.
|
||||
#
|
||||
|
||||
ifcapable !rtree {
|
||||
@@ -592,4 +594,20 @@ do_execsql_test 14.5 {
|
||||
3 42 49
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
do_execsql_test 15.0 {
|
||||
CREATE VIRTUAL TABLE rt USING rtree(id, x1,x2, y1,y2);
|
||||
CREATE TEMP TABLE t13(a, b, c);
|
||||
}
|
||||
do_execsql_test 15.1 {
|
||||
BEGIN;
|
||||
INSERT INTO rt VALUES(1,2,3,4,5);
|
||||
}
|
||||
breakpoint
|
||||
do_execsql_test 15.2 {
|
||||
DROP TABLE t13;
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Rename\sshell6.test\sto\sexpert1.test.\sHave\sit\sinvoke\sthe\ssqlite3_expert\sbinary\nif\sit\sis\spresent.
|
||||
D 2017-04-08T18:56:32.081
|
||||
C Merge\slatest\strunk\swith\sthis\sbranch.
|
||||
D 2017-04-08T19:00:37.586
|
||||
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
|
||||
@@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure cea63449647267beb335e899fd8a79778912ffa55d6b179730267b8ef84aa1aa x
|
||||
F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0
|
||||
F configure bddf7d1d945894b724e2b16a1266359a40abec2c798c95b4409a7ebf771c38ef x
|
||||
F configure.ac 901e8db2c211e8b655e51ee24f2b8faa33407acde87effc47f70380f3b04e452
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977
|
||||
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
|
||||
@@ -102,15 +102,15 @@ F ext/fts3/unicode/mkunicode.tcl ab0543a3b2399092ea2dd75df1bef333405b0d7f6b8c495
|
||||
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7
|
||||
F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1
|
||||
F ext/fts5/fts5Int.h 88c1a9a01cd5cd7b9a3c95699d1f61cdb277b2fa087a07d3fc989b49970437d9
|
||||
F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
|
||||
F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c
|
||||
F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2
|
||||
F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4
|
||||
F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2
|
||||
F ext/fts5/fts5_storage.c 8f0e65cb33bde8f449e1c9b4be4600d18b4da6e9
|
||||
F ext/fts5/fts5_index.c a3a9ae1c6f8a3652eb45dd732a71cdc92b48df047af134da38cd0c425649e042
|
||||
F ext/fts5/fts5_main.c 24cafdc44c06b9665d73c34b75966f6223e9299cc9fd10184c6bf888e3ff563f
|
||||
F ext/fts5/fts5_storage.c 7750986004f3f0c94619a85ecb5dd6cbef53e5e3853488e8a906c269d4d11db6
|
||||
F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a
|
||||
F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
|
||||
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
||||
@@ -121,7 +121,7 @@ F ext/fts5/fts5_vocab.c e44fefa7f0c1db252998af071daf06a7147e17e7
|
||||
F ext/fts5/fts5parse.y e51b375403421b8b37428a89b095d00597129aae
|
||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||
F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841
|
||||
F ext/fts5/test/fts5aa.test bd2d88182b9f7f30d300044048ad14683306b745
|
||||
F ext/fts5/test/fts5aa.test b3cb080db4851580705c5e261c9d4308edf030d5cbbc24b5d6668403b73f023b
|
||||
F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b
|
||||
F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f
|
||||
F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c
|
||||
@@ -221,7 +221,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c 92b9e404bd79cc76d3ef2b3a9e37bf775700f7d645466fd41d2e8742e3fa16fb
|
||||
F ext/misc/json1.c 312b4ddf4c7399dcbd2189f492e8ca92a872c2df7347473bfb38854f9d60c06a
|
||||
F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e
|
||||
@@ -274,9 +274,9 @@ F ext/rbu/sqlite3rbu.c 2a89efba9eeba8e6c89a498dc195e8efbdde2694
|
||||
F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba
|
||||
F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 0acd285bfacc347579a5df9fe947212fb99e2775a40c43f027c3a16936c58e7e
|
||||
F ext/rtree/rtree.c 37c603c6b8aed1a760661ceb5a025bd36bac14cf56d59949bd8de14b2a17e9ed
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec
|
||||
F ext/rtree/rtree1.test d5f0ba215b3bd1d05269ada86e74073b8445852aa0d33a63e10ec63a09c39473
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482
|
||||
F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0
|
||||
@@ -347,17 +347,17 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c 64ff65a01851a34c8145e5bc767df9e57d2f3c1acdc6aba334794b7c40c684e6
|
||||
F src/btree.c 24ae5472bd0b53b4130ecdda389deb621af721d1fcb50890b878102b00bd10fa
|
||||
F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d
|
||||
F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0
|
||||
F src/build.c 43f903c9082040ced2b421543cb0300c2973647d
|
||||
F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610
|
||||
F src/build.c 4026a9c554b233e50c5e9ad46963e676cf54dd2306d952aa1eaa07a1bc9ce14f
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c
|
||||
F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae
|
||||
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
|
||||
F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c
|
||||
F src/expr.c f12a581f342a6fd85d14c31e4fb84f16b3dd107f54d7728dddb62cebc79d7ce1
|
||||
F src/expr.c 6bce2cbdd822963cf28e782938a96274cc37f18ac28dec7a4e35ccac09f66ce8
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
|
||||
F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174
|
||||
@@ -370,7 +370,7 @@ F src/insert.c d4bb3a135948553d18cf992f76f7ed7b18aa0327f250607b5a6671e55d9947d5
|
||||
F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0
|
||||
F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9
|
||||
F src/main.c 4b93bda0f1f916f4cb618a6fce358f7e01ab060971c586c4cea90ad0c83a83f5
|
||||
F src/malloc.c 89c98e3619d362dcffa5c1c639b364b65b474751
|
||||
F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
@@ -397,19 +397,19 @@ F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105
|
||||
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc
|
||||
F src/pragma.c 157c323aef421d55905b42162ba16bc874c0dce3102c543b4092c202f881f2c6
|
||||
F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f
|
||||
F src/pragma.c 150821702fc90694b46c3432c1402fc970a4c5b8595cb13c21aeb568f9a78fc3
|
||||
F src/pragma.h 37a1311d0388db480388d7ec09054f7103045eff20d4971f8a433b77f40b9921
|
||||
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
|
||||
F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa
|
||||
F src/shell.c ceb2b2f1f958ea2c47a7f37972d0f715fbf9dcf6a34a5e98c886b85e3ce6a238
|
||||
F src/sqlite.h.in ae5c9cbf2e77492c319fca08769575d9695e64718a16d32324944d24e291bcf7
|
||||
F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664
|
||||
F src/shell.c 70f4957b988572315e97c56941fdc81fd35907fee36b7b2e7be5ec4c7e9d065d
|
||||
F src/sqlite.h.in 8ed51474c7a9edacbf328e2a6ce63de5cde8f50793c6063cb508f9de128e5a4c
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
|
||||
F src/sqliteInt.h 9af1569ac748f72169b4ad0004d03ea14c75b59eb955a2c0ecca75a16ea2015f
|
||||
F src/sqliteInt.h 36eec0868d25b50e64a05bc7355557a0aa9bd14330c16b7d7568520b2bf2bb4e
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@@ -464,28 +464,28 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff
|
||||
F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c de2ec4fed5aa9770791be7528a08597a77a36b2ffbbeb0c2cb6951e80357730b
|
||||
F src/tokenize.c 1003d6d90c6783206c711f0a9397656fa5b055209f4d092caa43bb3bf5215db5
|
||||
F src/treeview.c 84d0ac737e1231702679f0289180021e19c5cc186ec413e8dcb704a887c76ec8
|
||||
F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
|
||||
F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6
|
||||
F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569
|
||||
F src/vdbe.c f1acf5744cef62cbfd0b503d84289f840b6cdc980ac47b0d9632dfdb89cc79eb
|
||||
F src/vdbe.c 808fda3d50f544120d27c731449b524b4ec8f8b0f734b228831078f0ba53ecb9
|
||||
F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158
|
||||
F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe
|
||||
F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860
|
||||
F src/vdbeaux.c ecd0468611925d218e1eb4b3f538907904b136f0e15e333291a232b521bfcef1
|
||||
F src/vdbeaux.c 0ecacf8c7ca93e430b30819b8fc9b2c1ffe88202d1437e88c08a1f0b6159c58c
|
||||
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
|
||||
F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd
|
||||
F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face
|
||||
F src/vdbemem.c 8bb4dd22837da969bfda25ef3f92d41aaad192328f89a0951290d5e26ad7dbc4
|
||||
F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570c
|
||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||
F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
|
||||
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
|
||||
F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
|
||||
F src/where.c be352441558b55e21964ff53f0483776594789d0ede12dd9c58b022873c858f8
|
||||
F src/where.c 613b1cac781b2725bb0a841d5c264ae9475380ee3063c3ce9c81814b03a83c20
|
||||
F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4
|
||||
F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04
|
||||
F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c
|
||||
@@ -887,7 +887,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
|
||||
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023
|
||||
F test/insert4.test 46bead5f39e181850ee56adcf49d3a3157c460c52249211714612ac89fe34835
|
||||
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba
|
||||
F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a
|
||||
@@ -915,7 +915,7 @@ F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json101.test c0897616f32d95431f37fd291cb78742181980ac
|
||||
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
|
||||
F test/json102.test de1728e8ffde4a57cbc77b6815a60ccb82a6c759967be44e71952757e7d7947b
|
||||
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
|
||||
F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
@@ -1036,6 +1036,7 @@ F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
||||
F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264
|
||||
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
@@ -1123,6 +1124,7 @@ F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1
|
||||
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
|
||||
F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9
|
||||
F test/shell6.test ab1592ebe881371f651f18ee6a0df21cbfb5310f88cb832ab642d4038f679772
|
||||
F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
@@ -1170,7 +1172,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
||||
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
|
||||
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
||||
F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529
|
||||
F test/sync2.test 29af00fe9e468a1e20315d1edced8f8a32ac156df983ae9b53802e7d472675d5
|
||||
F test/sync2.test 6be8ed007fa063b147773c1982b5bdba97a32badc536bdc6077eff5cf8710ece
|
||||
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012
|
||||
@@ -1510,7 +1512,7 @@ F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl 2ffe6d5fdc2d3381621d6c77978ba054466e757f
|
||||
F tool/mkpragmatab.tcl 32bb40741df11bddc8451de9ea4d130e7b4476d8064794b1cf402ac110840fba
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||
F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e
|
||||
@@ -1573,7 +1575,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 bf10e68d9e4d5eae7ae6148a7ad64c9596f2ed8ccd36065adb09a1f9e7dae50b
|
||||
R e14200231c0812aa1e853be6a898ba2f
|
||||
P be0deff940bea4f653d644113f42529a32ff7039d1d168119233aaf000a22f40 204e72f0080e8f08f99978870bd3cb9d59b068ecffee82192d707c650548b43b
|
||||
R 6e0d9b80ca81b8d3b8a7b8f8dc2a80a0
|
||||
U dan
|
||||
Z b04d01a3056a5795f1f1bb4407f0bf9d
|
||||
Z 4063bdd74acb02b7df335075f419d3f7
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
be0deff940bea4f653d644113f42529a32ff7039d1d168119233aaf000a22f40
|
||||
e051e8f21b909c5e89a7203eef6501fecd64f82a634c4e10398b5ef7d716eb37
|
||||
+39
-38
@@ -4317,7 +4317,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
||||
CellInfo info;
|
||||
int iPage = pCur->iPage;
|
||||
memset(&info, 0, sizeof(info));
|
||||
btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
|
||||
btreeParseCell(pCur->apPage[iPage], pCur->ix, &info);
|
||||
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
|
||||
}
|
||||
#else
|
||||
@@ -4327,7 +4327,7 @@ static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
|
||||
if( pCur->info.nSize==0 ){
|
||||
int iPage = pCur->iPage;
|
||||
pCur->curFlags |= BTCF_ValidNKey;
|
||||
btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
|
||||
btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info);
|
||||
}else{
|
||||
assertCellInfo(pCur);
|
||||
}
|
||||
@@ -4534,7 +4534,7 @@ static int accessPayload(
|
||||
assert( pPage );
|
||||
assert( eOp==0 || eOp==1 );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
|
||||
assert( pCur->ix<pPage->nCell );
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
|
||||
getCellInfo(pCur);
|
||||
@@ -4721,7 +4721,7 @@ int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
|
||||
return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
|
||||
}
|
||||
|
||||
@@ -4783,7 +4783,7 @@ static const void *fetchPayload(
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->info.nSize>0 );
|
||||
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
|
||||
assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
|
||||
@@ -4834,8 +4834,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
|
||||
}
|
||||
pCur->info.nSize = 0;
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
pCur->iPage++;
|
||||
pCur->aiIdx[pCur->iPage] = 0;
|
||||
pCur->aiIdx[pCur->iPage++] = pCur->ix;
|
||||
pCur->ix = 0;
|
||||
return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage],
|
||||
pCur, pCur->curPagerFlags);
|
||||
}
|
||||
@@ -4883,6 +4883,7 @@ static void moveToParent(BtCursor *pCur){
|
||||
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
|
||||
pCur->info.nSize = 0;
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
pCur->ix = pCur->aiIdx[pCur->iPage-1];
|
||||
releasePageNotNull(pCur->apPage[pCur->iPage--]);
|
||||
}
|
||||
|
||||
@@ -4964,7 +4965,7 @@ static int moveToRoot(BtCursor *pCur){
|
||||
}
|
||||
|
||||
skip_init:
|
||||
pCur->aiIdx[0] = 0;
|
||||
pCur->ix = 0;
|
||||
pCur->info.nSize = 0;
|
||||
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
|
||||
@@ -4998,8 +4999,8 @@ static int moveToLeftmost(BtCursor *pCur){
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
|
||||
pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
|
||||
assert( pCur->ix<pPage->nCell );
|
||||
pgno = get4byte(findCell(pPage, pCur->ix));
|
||||
rc = moveToChild(pCur, pgno);
|
||||
}
|
||||
return rc;
|
||||
@@ -5024,11 +5025,11 @@ static int moveToRightmost(BtCursor *pCur){
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
||||
pCur->aiIdx[pCur->iPage] = pPage->nCell;
|
||||
pCur->ix = pPage->nCell;
|
||||
rc = moveToChild(pCur, pgno);
|
||||
if( rc ) return rc;
|
||||
}
|
||||
pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
|
||||
pCur->ix = pPage->nCell-1;
|
||||
assert( pCur->info.nSize==0 );
|
||||
assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
|
||||
return SQLITE_OK;
|
||||
@@ -5076,7 +5077,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
||||
for(ii=0; ii<pCur->iPage; ii++){
|
||||
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
|
||||
}
|
||||
assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
|
||||
assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 );
|
||||
assert( pCur->apPage[pCur->iPage]->leaf );
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
@@ -5223,7 +5224,7 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
upr = pPage->nCell-1;
|
||||
assert( biasRight==0 || biasRight==1 );
|
||||
idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
|
||||
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
||||
pCur->ix = (u16)idx;
|
||||
if( xRecordCompare==0 ){
|
||||
for(;;){
|
||||
i64 nCellKey;
|
||||
@@ -5242,7 +5243,7 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
if( lwr>upr ){ c = +1; break; }
|
||||
}else{
|
||||
assert( nCellKey==intKey );
|
||||
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
||||
pCur->ix = (u16)idx;
|
||||
if( !pPage->leaf ){
|
||||
lwr = idx;
|
||||
goto moveto_next_layer;
|
||||
@@ -5311,7 +5312,7 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto moveto_finish;
|
||||
}
|
||||
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
||||
pCur->ix = (u16)idx;
|
||||
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
|
||||
pCur->curFlags &= ~BTCF_ValidOvfl;
|
||||
if( rc ){
|
||||
@@ -5333,7 +5334,7 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
assert( c==0 );
|
||||
*pRes = 0;
|
||||
rc = SQLITE_OK;
|
||||
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
||||
pCur->ix = (u16)idx;
|
||||
if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
|
||||
goto moveto_finish;
|
||||
}
|
||||
@@ -5345,8 +5346,8 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
|
||||
assert( pPage->isInit );
|
||||
if( pPage->leaf ){
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
||||
assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
|
||||
pCur->ix = (u16)idx;
|
||||
*pRes = c;
|
||||
rc = SQLITE_OK;
|
||||
goto moveto_finish;
|
||||
@@ -5357,7 +5358,7 @@ moveto_next_layer:
|
||||
}else{
|
||||
chldPg = get4byte(findCell(pPage, lwr));
|
||||
}
|
||||
pCur->aiIdx[pCur->iPage] = (u16)lwr;
|
||||
pCur->ix = (u16)lwr;
|
||||
rc = moveToChild(pCur, chldPg);
|
||||
if( rc ) break;
|
||||
}
|
||||
@@ -5458,7 +5459,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
||||
}
|
||||
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
idx = ++pCur->aiIdx[pCur->iPage];
|
||||
idx = ++pCur->ix;
|
||||
assert( pPage->isInit );
|
||||
|
||||
/* If the database file is corrupt, it is possible for the value of idx
|
||||
@@ -5482,7 +5483,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
||||
}
|
||||
moveToParent(pCur);
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
}while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
|
||||
}while( pCur->ix>=pPage->nCell );
|
||||
if( pPage->intKey ){
|
||||
return sqlite3BtreeNext(pCur, pRes);
|
||||
}else{
|
||||
@@ -5506,8 +5507,8 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
*pRes = 0;
|
||||
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
|
||||
pCur->aiIdx[pCur->iPage]--;
|
||||
if( (++pCur->ix)>=pPage->nCell ){
|
||||
pCur->ix--;
|
||||
return btreeNext(pCur, pRes);
|
||||
}
|
||||
if( pPage->leaf ){
|
||||
@@ -5571,12 +5572,12 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
assert( pPage->isInit );
|
||||
if( !pPage->leaf ){
|
||||
int idx = pCur->aiIdx[pCur->iPage];
|
||||
int idx = pCur->ix;
|
||||
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
|
||||
if( rc ) return rc;
|
||||
rc = moveToRightmost(pCur);
|
||||
}else{
|
||||
while( pCur->aiIdx[pCur->iPage]==0 ){
|
||||
while( pCur->ix==0 ){
|
||||
if( pCur->iPage==0 ){
|
||||
pCur->eState = CURSOR_INVALID;
|
||||
*pRes = 1;
|
||||
@@ -5587,7 +5588,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
||||
assert( pCur->info.nSize==0 );
|
||||
assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
|
||||
|
||||
pCur->aiIdx[pCur->iPage]--;
|
||||
pCur->ix--;
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
if( pPage->intKey && !pPage->leaf ){
|
||||
rc = sqlite3BtreePrevious(pCur, pRes);
|
||||
@@ -5606,12 +5607,12 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
|
||||
pCur->info.nSize = 0;
|
||||
if( pCur->eState!=CURSOR_VALID
|
||||
|| pCur->aiIdx[pCur->iPage]==0
|
||||
|| pCur->ix==0
|
||||
|| pCur->apPage[pCur->iPage]->leaf==0
|
||||
){
|
||||
return btreePrevious(pCur, pRes);
|
||||
}
|
||||
pCur->aiIdx[pCur->iPage]--;
|
||||
pCur->ix--;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -7933,8 +7934,8 @@ static int balance(BtCursor *pCur){
|
||||
rc = balance_deeper(pPage, &pCur->apPage[1]);
|
||||
if( rc==SQLITE_OK ){
|
||||
pCur->iPage = 1;
|
||||
pCur->ix = 0;
|
||||
pCur->aiIdx[0] = 0;
|
||||
pCur->aiIdx[1] = 0;
|
||||
assert( pCur->apPage[1]->nOverflow );
|
||||
}
|
||||
}else{
|
||||
@@ -8163,7 +8164,7 @@ int sqlite3BtreeInsert(
|
||||
if( rc ) goto end_insert;
|
||||
assert( szNew==pPage->xCellSize(pPage, newCell) );
|
||||
assert( szNew <= MX_CELL_SIZE(pBt) );
|
||||
idx = pCur->aiIdx[pCur->iPage];
|
||||
idx = pCur->ix;
|
||||
if( loc==0 ){
|
||||
CellInfo info;
|
||||
assert( idx<pPage->nCell );
|
||||
@@ -8191,7 +8192,7 @@ int sqlite3BtreeInsert(
|
||||
if( rc ) goto end_insert;
|
||||
}else if( loc<0 && pPage->nCell>0 ){
|
||||
assert( pPage->leaf );
|
||||
idx = ++pCur->aiIdx[pCur->iPage];
|
||||
idx = ++pCur->ix;
|
||||
}else{
|
||||
assert( pPage->leaf );
|
||||
}
|
||||
@@ -8287,12 +8288,12 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
|
||||
assert( pCur->curFlags & BTCF_WriteFlag );
|
||||
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
||||
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
|
||||
|
||||
iCellDepth = pCur->iPage;
|
||||
iCellIdx = pCur->aiIdx[iCellDepth];
|
||||
iCellIdx = pCur->ix;
|
||||
pPage = pCur->apPage[iCellDepth];
|
||||
pCell = findCell(pPage, iCellIdx);
|
||||
|
||||
@@ -8409,7 +8410,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
|
||||
pCur->eState = CURSOR_SKIPNEXT;
|
||||
if( iCellIdx>=pPage->nCell ){
|
||||
pCur->skipNext = -1;
|
||||
pCur->aiIdx[iCellDepth] = pPage->nCell-1;
|
||||
pCur->ix = pPage->nCell-1;
|
||||
}else{
|
||||
pCur->skipNext = 1;
|
||||
}
|
||||
@@ -8922,16 +8923,16 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
|
||||
return moveToRoot(pCur);
|
||||
}
|
||||
moveToParent(pCur);
|
||||
}while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
|
||||
}while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell );
|
||||
|
||||
pCur->aiIdx[pCur->iPage]++;
|
||||
pCur->ix++;
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
}
|
||||
|
||||
/* Descend to the child node of the cell that the cursor currently
|
||||
** points at. This is the right-child if (iIdx==pPage->nCell).
|
||||
*/
|
||||
iIdx = pCur->aiIdx[pCur->iPage];
|
||||
iIdx = pCur->ix;
|
||||
if( iIdx==pPage->nCell ){
|
||||
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
|
||||
}else{
|
||||
|
||||
+4
-4
@@ -517,10 +517,10 @@ struct BtCursor {
|
||||
** initialized. */
|
||||
i8 iPage; /* Index of current page in apPage */
|
||||
u8 curIntKey; /* Value of apPage[0]->intKey */
|
||||
struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
|
||||
void *padding1; /* Make object size a multiple of 16 */
|
||||
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
|
||||
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
|
||||
u16 ix; /* Current index for apPage[iPage] */
|
||||
u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */
|
||||
struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */
|
||||
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+2
-2
@@ -3623,7 +3623,7 @@ void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
|
||||
sqlite3DbFree(db, pList->a[i].zName);
|
||||
}
|
||||
sqlite3DbFree(db, pList->a);
|
||||
sqlite3DbFree(db, pList);
|
||||
sqlite3DbFreeNN(db, pList);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3813,7 +3813,7 @@ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
|
||||
sqlite3ExprDelete(db, pItem->pOn);
|
||||
sqlite3IdListDelete(db, pItem->pUsing);
|
||||
}
|
||||
sqlite3DbFree(db, pList);
|
||||
sqlite3DbFreeNN(db, pList);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+36
-43
@@ -1038,7 +1038,7 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
|
||||
}
|
||||
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
|
||||
if( !ExprHasProperty(p, EP_Static) ){
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
}
|
||||
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
|
||||
@@ -1305,15 +1305,11 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
|
||||
Expr *pPriorSelectCol = 0;
|
||||
assert( db!=0 );
|
||||
if( p==0 ) return 0;
|
||||
pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
|
||||
pNew = sqlite3DbMallocRawNN(db,
|
||||
sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) );
|
||||
if( pNew==0 ) return 0;
|
||||
pNew->nExpr = i = p->nExpr;
|
||||
if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){}
|
||||
pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) );
|
||||
if( pItem==0 ){
|
||||
sqlite3DbFree(db, pNew);
|
||||
return 0;
|
||||
}
|
||||
pNew->nAlloc = pNew->nExpr = p->nExpr;
|
||||
pItem = pNew->a;
|
||||
pOldItem = p->a;
|
||||
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
|
||||
Expr *pOldExpr = pOldItem->pExpr;
|
||||
@@ -1404,7 +1400,7 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
|
||||
pNew->nId = p->nId;
|
||||
pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
|
||||
if( pNew->a==0 ){
|
||||
sqlite3DbFree(db, pNew);
|
||||
sqlite3DbFreeNN(db, pNew);
|
||||
return 0;
|
||||
}
|
||||
/* Note that because the size of the allocation for p->a[] is not
|
||||
@@ -1475,6 +1471,7 @@ ExprList *sqlite3ExprListAppend(
|
||||
ExprList *pList, /* List to which to append. Might be NULL */
|
||||
Expr *pExpr /* Expression to be appended. Might be NULL */
|
||||
){
|
||||
struct ExprList_item *pItem;
|
||||
sqlite3 *db = pParse->db;
|
||||
assert( db!=0 );
|
||||
if( pList==0 ){
|
||||
@@ -1483,23 +1480,20 @@ ExprList *sqlite3ExprListAppend(
|
||||
goto no_mem;
|
||||
}
|
||||
pList->nExpr = 0;
|
||||
pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0]));
|
||||
if( pList->a==0 ) goto no_mem;
|
||||
}else if( (pList->nExpr & (pList->nExpr-1))==0 ){
|
||||
struct ExprList_item *a;
|
||||
assert( pList->nExpr>0 );
|
||||
a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
|
||||
if( a==0 ){
|
||||
pList->nAlloc = 1;
|
||||
}else if( pList->nExpr==pList->nAlloc ){
|
||||
ExprList *pNew;
|
||||
pNew = sqlite3DbRealloc(db, pList,
|
||||
sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0]));
|
||||
if( pNew==0 ){
|
||||
goto no_mem;
|
||||
}
|
||||
pList->a = a;
|
||||
}
|
||||
assert( pList->a!=0 );
|
||||
if( 1 ){
|
||||
struct ExprList_item *pItem = &pList->a[pList->nExpr++];
|
||||
memset(pItem, 0, sizeof(*pItem));
|
||||
pItem->pExpr = pExpr;
|
||||
pList = pNew;
|
||||
pList->nAlloc *= 2;
|
||||
}
|
||||
pItem = &pList->a[pList->nExpr++];
|
||||
memset(pItem, 0, sizeof(*pItem));
|
||||
pItem->pExpr = pExpr;
|
||||
return pList;
|
||||
|
||||
no_mem:
|
||||
@@ -1556,20 +1550,19 @@ ExprList *sqlite3ExprListAppendVector(
|
||||
}
|
||||
}
|
||||
|
||||
if( pExpr->op==TK_SELECT ){
|
||||
if( pList && pList->a[iFirst].pExpr ){
|
||||
Expr *pFirst = pList->a[iFirst].pExpr;
|
||||
assert( pFirst->op==TK_SELECT_COLUMN );
|
||||
if( pExpr->op==TK_SELECT && pList ){
|
||||
Expr *pFirst = pList->a[iFirst].pExpr;
|
||||
assert( pFirst!=0 );
|
||||
assert( pFirst->op==TK_SELECT_COLUMN );
|
||||
|
||||
/* Store the SELECT statement in pRight so it will be deleted when
|
||||
** sqlite3ExprListDelete() is called */
|
||||
pFirst->pRight = pExpr;
|
||||
pExpr = 0;
|
||||
/* Store the SELECT statement in pRight so it will be deleted when
|
||||
** sqlite3ExprListDelete() is called */
|
||||
pFirst->pRight = pExpr;
|
||||
pExpr = 0;
|
||||
|
||||
/* Remember the size of the LHS in iTable so that we can check that
|
||||
** the RHS and LHS sizes match during code generation. */
|
||||
pFirst->iTable = pColumns->nId;
|
||||
}
|
||||
/* Remember the size of the LHS in iTable so that we can check that
|
||||
** the RHS and LHS sizes match during code generation. */
|
||||
pFirst->iTable = pColumns->nId;
|
||||
}
|
||||
|
||||
vector_append_error:
|
||||
@@ -1663,16 +1656,16 @@ void sqlite3ExprListCheckLength(
|
||||
** Delete an entire expression list.
|
||||
*/
|
||||
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
|
||||
int i;
|
||||
struct ExprList_item *pItem;
|
||||
assert( pList->a!=0 || pList->nExpr==0 );
|
||||
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
|
||||
int i = pList->nExpr;
|
||||
struct ExprList_item *pItem = pList->a;
|
||||
assert( pList->nExpr>0 );
|
||||
do{
|
||||
sqlite3ExprDelete(db, pItem->pExpr);
|
||||
sqlite3DbFree(db, pItem->zName);
|
||||
sqlite3DbFree(db, pItem->zSpan);
|
||||
}
|
||||
sqlite3DbFree(db, pList->a);
|
||||
sqlite3DbFree(db, pList);
|
||||
pItem++;
|
||||
}while( --i>0 );
|
||||
sqlite3DbFreeNN(db, pList);
|
||||
}
|
||||
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
if( pList ) exprListDeleteNN(db, pList);
|
||||
|
||||
+8
-3
@@ -474,11 +474,12 @@ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
|
||||
|
||||
/*
|
||||
** Free memory that might be associated with a particular database
|
||||
** connection.
|
||||
** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op.
|
||||
** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL.
|
||||
*/
|
||||
void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
void sqlite3DbFreeNN(sqlite3 *db, void *p){
|
||||
assert( db==0 || sqlite3_mutex_held(db->mutex) );
|
||||
if( p==0 ) return;
|
||||
assert( p!=0 );
|
||||
if( db ){
|
||||
if( db->pnBytesFreed ){
|
||||
measureAllocationSize(db, p);
|
||||
@@ -502,6 +503,10 @@ void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
assert( db==0 || sqlite3_mutex_held(db->mutex) );
|
||||
if( p ) sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the size of an existing memory allocation
|
||||
|
||||
+21
-18
@@ -1542,25 +1542,28 @@ void sqlite3Pragma(
|
||||
}
|
||||
/* Verify CHECK constraints */
|
||||
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
|
||||
int addrCkFault = sqlite3VdbeMakeLabel(v);
|
||||
int addrCkOk = sqlite3VdbeMakeLabel(v);
|
||||
ExprList *pCheck = pTab->pCheck;
|
||||
char *zErr;
|
||||
int k;
|
||||
pParse->iSelfTab = iDataCur;
|
||||
sqlite3ExprCachePush(pParse);
|
||||
for(k=pCheck->nExpr-1; k>0; k--){
|
||||
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
|
||||
ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
|
||||
if( db->mallocFailed==0 ){
|
||||
int addrCkFault = sqlite3VdbeMakeLabel(v);
|
||||
int addrCkOk = sqlite3VdbeMakeLabel(v);
|
||||
char *zErr;
|
||||
int k;
|
||||
pParse->iSelfTab = iDataCur;
|
||||
sqlite3ExprCachePush(pParse);
|
||||
for(k=pCheck->nExpr-1; k>0; k--){
|
||||
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
|
||||
}
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
|
||||
SQLITE_JUMPIFNULL);
|
||||
sqlite3VdbeResolveLabel(v, addrCkFault);
|
||||
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
|
||||
pTab->zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeResolveLabel(v, addrCkOk);
|
||||
sqlite3ExprCachePop(pParse);
|
||||
}
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
|
||||
SQLITE_JUMPIFNULL);
|
||||
sqlite3VdbeResolveLabel(v, addrCkFault);
|
||||
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
|
||||
pTab->zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeResolveLabel(v, addrCkOk);
|
||||
sqlite3ExprCachePop(pParse);
|
||||
sqlite3ExprListDelete(db, pCheck);
|
||||
}
|
||||
/* Validate index entries for the current row */
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
|
||||
|
||||
+1
-1
@@ -417,7 +417,7 @@ static const PragmaName aPragmaName[] = {
|
||||
#endif
|
||||
{/* zName: */ "optimize",
|
||||
/* ePragTyp: */ PragTyp_OPTIMIZE,
|
||||
/* ePragFlg: */ PragFlg_Result1,
|
||||
/* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
|
||||
+3
-3
@@ -76,7 +76,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
sqlite3ExprDelete(db, p->pOffset);
|
||||
if( p->pWith ) sqlite3WithDelete(db, p->pWith);
|
||||
if( bFree ) sqlite3DbFree(db, p);
|
||||
if( bFree ) sqlite3DbFreeNN(db, p);
|
||||
p = pPrior;
|
||||
bFree = 1;
|
||||
}
|
||||
@@ -1055,7 +1055,7 @@ void sqlite3KeyInfoUnref(KeyInfo *p){
|
||||
if( p ){
|
||||
assert( p->nRef>0 );
|
||||
p->nRef--;
|
||||
if( p->nRef==0 ) sqlite3DbFree(p->db, p);
|
||||
if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2900,7 +2900,7 @@ static int multiSelectOrderBy(
|
||||
if( pNew==0 ) return SQLITE_NOMEM_BKPT;
|
||||
pNew->flags |= EP_IntValue;
|
||||
pNew->u.iValue = i;
|
||||
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
|
||||
p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
|
||||
if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
|
||||
}
|
||||
}
|
||||
|
||||
+154
-47
@@ -1488,13 +1488,72 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
|
||||
raw_printf(out,"'");
|
||||
}
|
||||
|
||||
/*
|
||||
** Find a string that is not found anywhere in z[]. Return a pointer
|
||||
** to that string.
|
||||
**
|
||||
** Try to use zA and zB first. If both of those are already found in z[]
|
||||
** then make up some string and store it in the buffer zBuf.
|
||||
*/
|
||||
static const char *unused_string(
|
||||
const char *z, /* Result must not appear anywhere in z */
|
||||
const char *zA, const char *zB, /* Try these first */
|
||||
char *zBuf /* Space to store a generated string */
|
||||
){
|
||||
unsigned i = 0;
|
||||
if( strstr(z, zA)==0 ) return zA;
|
||||
if( strstr(z, zB)==0 ) return zB;
|
||||
do{
|
||||
sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
|
||||
}while( strstr(z,zBuf)!=0 );
|
||||
return zBuf;
|
||||
}
|
||||
|
||||
/*
|
||||
** Output the given string as a quoted string using SQL quoting conventions.
|
||||
**
|
||||
** The "\n" and "\r" characters are converted to char(10) and char(13)
|
||||
** to prevent them from being transformed by end-of-line translators.
|
||||
** See also: output_quoted_escaped_string()
|
||||
*/
|
||||
static void output_quoted_string(FILE *out, const char *z){
|
||||
int i;
|
||||
char c;
|
||||
setBinaryMode(out, 1);
|
||||
for(i=0; (c = z[i])!=0 && c!='\''; i++){}
|
||||
if( c==0 ){
|
||||
utf8_printf(out,"'%s'",z);
|
||||
}else{
|
||||
raw_printf(out, "'");
|
||||
while( *z ){
|
||||
for(i=0; (c = z[i])!=0 && c!='\''; i++){}
|
||||
if( c=='\'' ) i++;
|
||||
if( i ){
|
||||
utf8_printf(out, "%.*s", i, z);
|
||||
z += i;
|
||||
}
|
||||
if( c=='\'' ){
|
||||
raw_printf(out, "'");
|
||||
continue;
|
||||
}
|
||||
if( c==0 ){
|
||||
break;
|
||||
}
|
||||
z++;
|
||||
}
|
||||
raw_printf(out, "'");
|
||||
}
|
||||
setTextMode(out, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Output the given string as a quoted string using SQL quoting conventions.
|
||||
** Additionallly , escape the "\n" and "\r" characters so that they do not
|
||||
** get corrupted by end-of-line translation facilities in some operating
|
||||
** systems.
|
||||
**
|
||||
** This is like output_quoted_string() but with the addition of the \r\n
|
||||
** escape mechanism.
|
||||
*/
|
||||
static void output_quoted_escaped_string(FILE *out, const char *z){
|
||||
int i;
|
||||
char c;
|
||||
setBinaryMode(out, 1);
|
||||
@@ -1502,40 +1561,52 @@ static void output_quoted_string(FILE *out, const char *z){
|
||||
if( c==0 ){
|
||||
utf8_printf(out,"'%s'",z);
|
||||
}else{
|
||||
int inQuote = 0;
|
||||
int bStarted = 0;
|
||||
const char *zNL = 0;
|
||||
const char *zCR = 0;
|
||||
int nNL = 0;
|
||||
int nCR = 0;
|
||||
char zBuf1[20], zBuf2[20];
|
||||
for(i=0; z[i]; i++){
|
||||
if( z[i]=='\n' ) nNL++;
|
||||
if( z[i]=='\r' ) nCR++;
|
||||
}
|
||||
if( nNL ){
|
||||
raw_printf(out, "replace(");
|
||||
zNL = unused_string(z, "\\n", "\\012", zBuf1);
|
||||
}
|
||||
if( nCR ){
|
||||
raw_printf(out, "replace(");
|
||||
zCR = unused_string(z, "\\r", "\\015", zBuf2);
|
||||
}
|
||||
raw_printf(out, "'");
|
||||
while( *z ){
|
||||
for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
|
||||
if( c=='\'' ) i++;
|
||||
if( i ){
|
||||
if( !inQuote ){
|
||||
if( bStarted ) raw_printf(out, "||");
|
||||
raw_printf(out, "'");
|
||||
inQuote = 1;
|
||||
}
|
||||
utf8_printf(out, "%.*s", i, z);
|
||||
z += i;
|
||||
bStarted = 1;
|
||||
}
|
||||
if( c=='\'' ){
|
||||
raw_printf(out, "'");
|
||||
continue;
|
||||
}
|
||||
if( inQuote ){
|
||||
raw_printf(out, "'");
|
||||
inQuote = 0;
|
||||
}
|
||||
if( c==0 ){
|
||||
break;
|
||||
}
|
||||
for(i=0; (c = z[i])=='\r' || c=='\n'; i++){
|
||||
if( bStarted ) raw_printf(out, "||");
|
||||
raw_printf(out, "char(%d)", c);
|
||||
bStarted = 1;
|
||||
z++;
|
||||
if( c=='\n' ){
|
||||
raw_printf(out, "%s", zNL);
|
||||
continue;
|
||||
}
|
||||
z += i;
|
||||
raw_printf(out, "%s", zCR);
|
||||
}
|
||||
raw_printf(out, "'");
|
||||
if( nCR ){
|
||||
raw_printf(out, ",'%s',char(13))", zCR);
|
||||
}
|
||||
if( nNL ){
|
||||
raw_printf(out, ",'%s',char(10))", zNL);
|
||||
}
|
||||
if( inQuote ) raw_printf(out, "'");
|
||||
}
|
||||
setTextMode(out, 1);
|
||||
}
|
||||
@@ -1998,21 +2069,53 @@ static int shell_callback(
|
||||
setTextMode(p->out, 1);
|
||||
break;
|
||||
}
|
||||
case MODE_Quote:
|
||||
case MODE_Insert: {
|
||||
if( azArg==0 ) break;
|
||||
if( p->cMode==MODE_Insert ){
|
||||
utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
|
||||
if( p->showHeader ){
|
||||
raw_printf(p->out,"(");
|
||||
for(i=0; i<nArg; i++){
|
||||
char *zSep = i>0 ? ",": "";
|
||||
utf8_printf(p->out, "%s%s", zSep, azCol[i]);
|
||||
utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
|
||||
if( p->showHeader ){
|
||||
raw_printf(p->out,"(");
|
||||
for(i=0; i<nArg; i++){
|
||||
if( i>0 ) raw_printf(p->out, ",");
|
||||
if( quoteChar(azCol[i]) ){
|
||||
char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
|
||||
utf8_printf(p->out, "%s", z);
|
||||
sqlite3_free(z);
|
||||
}else{
|
||||
raw_printf(p->out, "%s", azCol[i]);
|
||||
}
|
||||
raw_printf(p->out,")");
|
||||
}
|
||||
raw_printf(p->out," VALUES(");
|
||||
}else if( p->cnt==0 && p->showHeader ){
|
||||
raw_printf(p->out,")");
|
||||
}
|
||||
p->cnt++;
|
||||
for(i=0; i<nArg; i++){
|
||||
raw_printf(p->out, i>0 ? "," : " VALUES(");
|
||||
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
|
||||
utf8_printf(p->out,"NULL");
|
||||
}else if( aiType && aiType[i]==SQLITE_TEXT ){
|
||||
output_quoted_escaped_string(p->out, azArg[i]);
|
||||
}else if( aiType && aiType[i]==SQLITE_INTEGER ){
|
||||
utf8_printf(p->out,"%s", azArg[i]);
|
||||
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
|
||||
char z[50];
|
||||
double r = sqlite3_column_double(p->pStmt, i);
|
||||
sqlite3_snprintf(50,z,"%!.20g", r);
|
||||
raw_printf(p->out, "%s", z);
|
||||
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
|
||||
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
|
||||
int nBlob = sqlite3_column_bytes(p->pStmt, i);
|
||||
output_hex_blob(p->out, pBlob, nBlob);
|
||||
}else if( isNumber(azArg[i], 0) ){
|
||||
utf8_printf(p->out,"%s", azArg[i]);
|
||||
}else{
|
||||
output_quoted_escaped_string(p->out, azArg[i]);
|
||||
}
|
||||
}
|
||||
raw_printf(p->out,");\n");
|
||||
break;
|
||||
}
|
||||
case MODE_Quote: {
|
||||
if( azArg==0 ) break;
|
||||
if( p->cnt==0 && p->showHeader ){
|
||||
for(i=0; i<nArg; i++){
|
||||
if( i>0 ) raw_printf(p->out, ",");
|
||||
output_quoted_string(p->out, azCol[i]);
|
||||
@@ -2021,32 +2124,29 @@ static int shell_callback(
|
||||
}
|
||||
p->cnt++;
|
||||
for(i=0; i<nArg; i++){
|
||||
char *zSep = i>0 ? ",": "";
|
||||
if( i>0 ) raw_printf(p->out, ",");
|
||||
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
|
||||
utf8_printf(p->out,"%sNULL",zSep);
|
||||
utf8_printf(p->out,"NULL");
|
||||
}else if( aiType && aiType[i]==SQLITE_TEXT ){
|
||||
if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
|
||||
output_quoted_string(p->out, azArg[i]);
|
||||
}else if( aiType && aiType[i]==SQLITE_INTEGER ){
|
||||
utf8_printf(p->out,"%s%s",zSep, azArg[i]);
|
||||
utf8_printf(p->out,"%s", azArg[i]);
|
||||
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
|
||||
char z[50];
|
||||
double r = sqlite3_column_double(p->pStmt, i);
|
||||
sqlite3_snprintf(50,z,"%!.20g", r);
|
||||
raw_printf(p->out, "%s%s", zSep, z);
|
||||
raw_printf(p->out, "%s", z);
|
||||
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
|
||||
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
|
||||
int nBlob = sqlite3_column_bytes(p->pStmt, i);
|
||||
if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
|
||||
output_hex_blob(p->out, pBlob, nBlob);
|
||||
}else if( isNumber(azArg[i], 0) ){
|
||||
utf8_printf(p->out,"%s%s",zSep, azArg[i]);
|
||||
utf8_printf(p->out,"%s", azArg[i]);
|
||||
}else{
|
||||
if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
|
||||
output_quoted_string(p->out, azArg[i]);
|
||||
}
|
||||
}
|
||||
raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
|
||||
raw_printf(p->out,"\n");
|
||||
break;
|
||||
}
|
||||
case MODE_Ascii: {
|
||||
@@ -4331,29 +4431,30 @@ static int lintFkeyIndexes(
|
||||
"SELECT "
|
||||
" 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '"
|
||||
" || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
|
||||
" || fkey_collate_clause(f.[table], f.[to], s.name, f.[from]),' AND ')"
|
||||
" || fkey_collate_clause("
|
||||
" f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')"
|
||||
", "
|
||||
" 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
|
||||
" || group_concat('*=?', ' AND ') || ')'"
|
||||
", "
|
||||
" s.name || '(' || group_concat(f.[from], ', ') || ')'"
|
||||
", "
|
||||
" f.[table] || '(' || group_concat(COALESCE(f.[to], "
|
||||
" (SELECT name FROM pragma_table_info(f.[table]) WHERE pk=seq+1)"
|
||||
" )) || ')'"
|
||||
" f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'"
|
||||
", "
|
||||
" 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
|
||||
" || ' ON ' || quote(s.name) || '('"
|
||||
" || group_concat(quote(f.[from]) ||"
|
||||
" fkey_collate_clause(f.[table], f.[to], s.name, f.[from]), ', ')"
|
||||
" fkey_collate_clause("
|
||||
" f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')"
|
||||
" || ');'"
|
||||
", "
|
||||
" f.[table] "
|
||||
|
||||
"FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f "
|
||||
"LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
|
||||
"GROUP BY s.name, f.id "
|
||||
"ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
|
||||
;
|
||||
const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
|
||||
|
||||
for(i=2; i<nArg; i++){
|
||||
int n = (int)strlen(azArg[i]);
|
||||
@@ -4402,7 +4503,10 @@ static int lintFkeyIndexes(
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
if( SQLITE_ROW==sqlite3_step(pExplain) ){
|
||||
const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
|
||||
res = (0==sqlite3_strglob(zGlob, zPlan));
|
||||
res = (
|
||||
0==sqlite3_strglob(zGlob, zPlan)
|
||||
|| 0==sqlite3_strglob(zGlobIPK, zPlan)
|
||||
);
|
||||
}
|
||||
rc = sqlite3_finalize(pExplain);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
@@ -4680,6 +4784,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
|
||||
const char *zLike = 0;
|
||||
int i;
|
||||
int savedShowHeader = p->showHeader;
|
||||
ShellClearFlag(p, SHFLG_PreserveRowid);
|
||||
for(i=1; i<nArg; i++){
|
||||
if( azArg[i][0]=='-' ){
|
||||
@@ -4715,6 +4820,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
|
||||
raw_printf(p->out, "BEGIN TRANSACTION;\n");
|
||||
p->writableSchema = 0;
|
||||
p->showHeader = 0;
|
||||
/* Set writable_schema=ON since doing so forces SQLite to initialize
|
||||
** as much of the schema as it can even if the sqlite_master table is
|
||||
** corrupt. */
|
||||
@@ -4756,6 +4862,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
|
||||
sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
|
||||
raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
|
||||
p->showHeader = savedShowHeader;
|
||||
}else
|
||||
|
||||
if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
|
||||
|
||||
@@ -2210,9 +2210,6 @@ int sqlite3_total_changes(sqlite3*);
|
||||
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
|
||||
** SQL statements is a no-op and has no effect on SQL statements
|
||||
** that are started after the sqlite3_interrupt() call returns.
|
||||
**
|
||||
** If the database connection closes while [sqlite3_interrupt()]
|
||||
** is running then bad things will likely happen.
|
||||
*/
|
||||
void sqlite3_interrupt(sqlite3*);
|
||||
|
||||
|
||||
+3
-1
@@ -2447,6 +2447,7 @@ struct Expr {
|
||||
*/
|
||||
struct ExprList {
|
||||
int nExpr; /* Number of expressions on the list */
|
||||
int nAlloc; /* Number of a[] slots allocated */
|
||||
struct ExprList_item { /* For each expression in the list */
|
||||
Expr *pExpr; /* The parse tree for this expression */
|
||||
char *zName; /* Token associated with this expression */
|
||||
@@ -2462,7 +2463,7 @@ struct ExprList {
|
||||
} x;
|
||||
int iConstExprReg; /* Register in which Expr value is cached */
|
||||
} u;
|
||||
} *a; /* Alloc a power of two greater or equal to nExpr */
|
||||
} a[1]; /* One slot for each expression in the list */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3480,6 +3481,7 @@ void *sqlite3Realloc(void*, u64);
|
||||
void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
|
||||
void *sqlite3DbRealloc(sqlite3 *, void *, u64);
|
||||
void sqlite3DbFree(sqlite3*, void*);
|
||||
void sqlite3DbFreeNN(sqlite3*, void*);
|
||||
int sqlite3MallocSize(void*);
|
||||
int sqlite3DbMallocSize(sqlite3*, void*);
|
||||
void *sqlite3ScratchMalloc(int);
|
||||
|
||||
+1
-1
@@ -604,7 +604,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
while( pParse->pAinc ){
|
||||
AutoincInfo *p = pParse->pAinc;
|
||||
pParse->pAinc = p->pNext;
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
while( pParse->pZombieTab ){
|
||||
Table *p = pParse->pZombieTab;
|
||||
|
||||
+19
-13
@@ -2440,7 +2440,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
|
||||
**
|
||||
** The value extracted is stored in register P3.
|
||||
**
|
||||
** If the column contains fewer than P2 fields, then extract a NULL. Or,
|
||||
** If the record contains fewer than P2 fields, then extract a NULL. Or,
|
||||
** if the P4 argument is a P4_MEM use the value of the P4 argument as
|
||||
** the result.
|
||||
**
|
||||
@@ -2449,7 +2449,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
|
||||
** The first OP_Column against a pseudo-table after the value of the content
|
||||
** register has changed should have this bit set.
|
||||
**
|
||||
** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
|
||||
** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then
|
||||
** the result is guaranteed to only be used as the argument of a length()
|
||||
** or typeof() function, respectively. The loading of large blobs can be
|
||||
** skipped for length() and all content loading can be skipped for typeof().
|
||||
@@ -2710,18 +2710,18 @@ op_column_out:
|
||||
*/
|
||||
case OP_Affinity: {
|
||||
const char *zAffinity; /* The affinity to be applied */
|
||||
char cAff; /* A single character of affinity */
|
||||
|
||||
zAffinity = pOp->p4.z;
|
||||
assert( zAffinity!=0 );
|
||||
assert( pOp->p2>0 );
|
||||
assert( zAffinity[pOp->p2]==0 );
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
while( (cAff = *(zAffinity++))!=0 ){
|
||||
do{
|
||||
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
|
||||
assert( memIsValid(pIn1) );
|
||||
applyAffinity(pIn1, cAff, encoding);
|
||||
applyAffinity(pIn1, *(zAffinity++), encoding);
|
||||
pIn1++;
|
||||
}
|
||||
}while( zAffinity[0] );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2892,7 +2892,6 @@ case OP_MakeRecord: {
|
||||
pOut->u.nZero = nZero;
|
||||
pOut->flags |= MEM_Zero;
|
||||
}
|
||||
pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
|
||||
REGISTER_TRACE(pOp->p3, pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
break;
|
||||
@@ -4077,7 +4076,7 @@ case OP_Found: { /* jump, in3 */
|
||||
}
|
||||
}
|
||||
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
|
||||
if( pFree ) sqlite3DbFree(db, pFree);
|
||||
if( pFree ) sqlite3DbFreeNN(db, pFree);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
@@ -5387,10 +5386,17 @@ case OP_IdxGE: { /* jump */
|
||||
** might be moved into the newly deleted root page in order to keep all
|
||||
** root pages contiguous at the beginning of the database. The former
|
||||
** value of the root page that moved - its value before the move occurred -
|
||||
** is stored in register P2. If no page
|
||||
** movement was required (because the table being dropped was already
|
||||
** the last one in the database) then a zero is stored in register P2.
|
||||
** If AUTOVACUUM is disabled then a zero is stored in register P2.
|
||||
** is stored in register P2. If no page movement was required (because the
|
||||
** table being dropped was already the last one in the database) then a
|
||||
** zero is stored in register P2. If AUTOVACUUM is disabled then a zero
|
||||
** is stored in register P2.
|
||||
**
|
||||
** This opcode throws an error if there are any active reader VMs when
|
||||
** it is invoked. This is done to avoid the difficulty associated with
|
||||
** updating existing cursors when a root page is moved in an AUTOVACUUM
|
||||
** database. This error is thrown even if the database is not an AUTOVACUUM
|
||||
** db in order to avoid introducing an incompatibility between autovacuum
|
||||
** and non-autovacuum modes.
|
||||
**
|
||||
** See also: Clear
|
||||
*/
|
||||
@@ -5595,7 +5601,7 @@ case OP_ParseSchema: {
|
||||
assert( !db->mallocFailed );
|
||||
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
|
||||
if( rc==SQLITE_OK ) rc = initData.rc;
|
||||
sqlite3DbFree(db, zSql);
|
||||
sqlite3DbFreeNN(db, zSql);
|
||||
db->init.busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-9
@@ -811,7 +811,7 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){
|
||||
*/
|
||||
static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
|
||||
if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
|
||||
sqlite3DbFree(db, pDef);
|
||||
sqlite3DbFreeNN(db, pDef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -822,11 +822,11 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int);
|
||||
*/
|
||||
static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
|
||||
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
|
||||
freeEphemeralFunction(db, p->pFunc);
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
static void freeP4(sqlite3 *db, int p4type, void *p4){
|
||||
assert( db );
|
||||
@@ -885,8 +885,8 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
|
||||
sqlite3DbFree(db, pOp->zComment);
|
||||
#endif
|
||||
}
|
||||
sqlite3DbFreeNN(db, aOp);
|
||||
}
|
||||
sqlite3DbFree(db, aOp);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1559,7 +1559,7 @@ static void releaseMemArray(Mem *p, int N){
|
||||
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
|
||||
sqlite3VdbeMemRelease(p);
|
||||
}else if( p->szMalloc ){
|
||||
sqlite3DbFree(db, p->zMalloc);
|
||||
sqlite3DbFreeNN(db, p->zMalloc);
|
||||
p->szMalloc = 0;
|
||||
}
|
||||
|
||||
@@ -2930,7 +2930,6 @@ int sqlite3VdbeReset(Vdbe *p){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
p->iCurrentTime = 0;
|
||||
p->magic = VDBE_MAGIC_RESET;
|
||||
return p->rc & db->errMask;
|
||||
}
|
||||
@@ -3040,7 +3039,7 @@ void sqlite3VdbeDelete(Vdbe *p){
|
||||
}
|
||||
p->magic = VDBE_MAGIC_DEAD;
|
||||
p->db = 0;
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4599,7 +4598,7 @@ static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
|
||||
Mem *pMem = &p->aMem[i];
|
||||
if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
|
||||
}
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
|
||||
@@ -4666,7 +4665,7 @@ void sqlite3VdbePreUpdateHook(
|
||||
for(i=0; i<pCsr->nField; i++){
|
||||
sqlite3VdbeMemRelease(&preupdate.aNew[i]);
|
||||
}
|
||||
sqlite3DbFree(db, preupdate.aNew);
|
||||
sqlite3DbFreeNN(db, preupdate.aNew);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
|
||||
|
||||
+22
-16
@@ -131,7 +131,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
|
||||
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
|
||||
bPreserve = 0;
|
||||
}else{
|
||||
if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
|
||||
if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
|
||||
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
|
||||
}
|
||||
if( pMem->zMalloc==0 ){
|
||||
@@ -341,7 +341,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
|
||||
ctx.pFunc = pFunc;
|
||||
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
|
||||
assert( (pMem->flags & MEM_Dyn)==0 );
|
||||
if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
|
||||
if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
|
||||
memcpy(pMem, &t, sizeof(t));
|
||||
rc = ctx.isError;
|
||||
}
|
||||
@@ -392,7 +392,7 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
|
||||
vdbeMemClearExternAndSetNull(p);
|
||||
}
|
||||
if( p->szMalloc ){
|
||||
sqlite3DbFree(p->db, p->zMalloc);
|
||||
sqlite3DbFreeNN(p->db, p->zMalloc);
|
||||
p->szMalloc = 0;
|
||||
}
|
||||
p->z = 0;
|
||||
@@ -420,7 +420,7 @@ void sqlite3VdbeMemRelease(Mem *p){
|
||||
** If the double is out of range of a 64-bit signed integer then
|
||||
** return the closest available 64-bit signed integer.
|
||||
*/
|
||||
static i64 doubleToInt64(double r){
|
||||
static SQLITE_NOINLINE i64 doubleToInt64(double r){
|
||||
#ifdef SQLITE_OMIT_FLOATING_POINT
|
||||
/* When floating-point is omitted, double and int64 are the same thing */
|
||||
return r;
|
||||
@@ -456,6 +456,11 @@ static i64 doubleToInt64(double r){
|
||||
**
|
||||
** If pMem represents a string value, its encoding might be changed.
|
||||
*/
|
||||
static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){
|
||||
i64 value = 0;
|
||||
sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
|
||||
return value;
|
||||
}
|
||||
i64 sqlite3VdbeIntValue(Mem *pMem){
|
||||
int flags;
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
@@ -466,10 +471,8 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
|
||||
}else if( flags & MEM_Real ){
|
||||
return doubleToInt64(pMem->u.r);
|
||||
}else if( flags & (MEM_Str|MEM_Blob) ){
|
||||
i64 value = 0;
|
||||
assert( pMem->z || pMem->n==0 );
|
||||
sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
|
||||
return value;
|
||||
return memIntValue(pMem);
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
@@ -481,6 +484,12 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
|
||||
** value. If it is a string or blob, try to convert it to a double.
|
||||
** If it is a NULL, return 0.0.
|
||||
*/
|
||||
static SQLITE_NOINLINE double memRealValue(Mem *pMem){
|
||||
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
|
||||
double val = (double)0;
|
||||
sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
|
||||
return val;
|
||||
}
|
||||
double sqlite3VdbeRealValue(Mem *pMem){
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
|
||||
@@ -489,10 +498,7 @@ double sqlite3VdbeRealValue(Mem *pMem){
|
||||
}else if( pMem->flags & MEM_Int ){
|
||||
return (double)pMem->u.i;
|
||||
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
|
||||
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
|
||||
double val = (double)0;
|
||||
sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
|
||||
return val;
|
||||
return memRealValue(pMem);
|
||||
}else{
|
||||
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
|
||||
return (double)0;
|
||||
@@ -1117,7 +1123,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
|
||||
pRec->aMem[i].db = db;
|
||||
}
|
||||
}else{
|
||||
sqlite3DbFree(db, pRec);
|
||||
sqlite3DbFreeNN(db, pRec);
|
||||
pRec = 0;
|
||||
}
|
||||
}
|
||||
@@ -1229,7 +1235,7 @@ static int valueFromFunction(
|
||||
for(i=0; i<nVal; i++){
|
||||
sqlite3ValueFree(apVal[i]);
|
||||
}
|
||||
sqlite3DbFree(db, apVal);
|
||||
sqlite3DbFreeNN(db, apVal);
|
||||
}
|
||||
|
||||
*ppVal = pVal;
|
||||
@@ -1428,7 +1434,7 @@ static void recordFunc(
|
||||
putVarint32(&aRet[1], iSerial);
|
||||
sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
|
||||
sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
|
||||
sqlite3DbFree(db, aRet);
|
||||
sqlite3DbFreeNN(db, aRet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1655,7 +1661,7 @@ void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
|
||||
sqlite3VdbeMemRelease(&aMem[i]);
|
||||
}
|
||||
sqlite3KeyInfoUnref(pRec->pKeyInfo);
|
||||
sqlite3DbFree(db, pRec);
|
||||
sqlite3DbFreeNN(db, pRec);
|
||||
}
|
||||
}
|
||||
#endif /* ifdef SQLITE_ENABLE_STAT4 */
|
||||
@@ -1679,7 +1685,7 @@ void sqlite3ValueSetStr(
|
||||
void sqlite3ValueFree(sqlite3_value *v){
|
||||
if( !v ) return;
|
||||
sqlite3VdbeMemRelease((Mem *)v);
|
||||
sqlite3DbFree(((Mem*)v)->db, v);
|
||||
sqlite3DbFreeNN(((Mem*)v)->db, v);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+26
-27
@@ -858,37 +858,36 @@ static int vdbeSorterCompareInt(
|
||||
assert( (s1>0 && s1<7) || s1==8 || s1==9 );
|
||||
assert( (s2>0 && s2<7) || s2==8 || s2==9 );
|
||||
|
||||
if( s1>7 && s2>7 ){
|
||||
if( s1==s2 ){
|
||||
/* The two values have the same sign. Compare using memcmp(). */
|
||||
static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 };
|
||||
const u8 n = aLen[s1];
|
||||
int i;
|
||||
res = 0;
|
||||
for(i=0; i<n; i++){
|
||||
if( (res = v1[i] - v2[i])!=0 ){
|
||||
if( ((v1[0] ^ v2[0]) & 0x80)!=0 ){
|
||||
res = v1[0] & 0x80 ? -1 : +1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else if( s1>7 && s2>7 ){
|
||||
res = s1 - s2;
|
||||
}else{
|
||||
if( s1==s2 ){
|
||||
if( (*v1 ^ *v2) & 0x80 ){
|
||||
/* The two values have different signs */
|
||||
res = (*v1 & 0x80) ? -1 : +1;
|
||||
}else{
|
||||
/* The two values have the same sign. Compare using memcmp(). */
|
||||
static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
|
||||
int i;
|
||||
res = 0;
|
||||
for(i=0; i<aLen[s1]; i++){
|
||||
if( (res = v1[i] - v2[i]) ) break;
|
||||
}
|
||||
}
|
||||
if( s2>7 ){
|
||||
res = +1;
|
||||
}else if( s1>7 ){
|
||||
res = -1;
|
||||
}else{
|
||||
if( s2>7 ){
|
||||
res = +1;
|
||||
}else if( s1>7 ){
|
||||
res = -1;
|
||||
}else{
|
||||
res = s1 - s2;
|
||||
}
|
||||
assert( res!=0 );
|
||||
res = s1 - s2;
|
||||
}
|
||||
assert( res!=0 );
|
||||
|
||||
if( res>0 ){
|
||||
if( *v1 & 0x80 ) res = -1;
|
||||
}else{
|
||||
if( *v2 & 0x80 ) res = +1;
|
||||
}
|
||||
if( res>0 ){
|
||||
if( *v1 & 0x80 ) res = -1;
|
||||
}else{
|
||||
if( *v2 & 0x80 ) res = +1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-9
@@ -1786,7 +1786,7 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
|
||||
p->u.vtab.idxStr = 0;
|
||||
}else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
|
||||
sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
|
||||
sqlite3DbFree(db, p->u.btree.pIndex);
|
||||
sqlite3DbFreeNN(db, p->u.btree.pIndex);
|
||||
p->u.btree.pIndex = 0;
|
||||
}
|
||||
}
|
||||
@@ -1796,7 +1796,7 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
|
||||
** Deallocate internal memory used by a WhereLoop object
|
||||
*/
|
||||
static void whereLoopClear(sqlite3 *db, WhereLoop *p){
|
||||
if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
|
||||
if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
|
||||
whereLoopClearUnion(db, p);
|
||||
whereLoopInit(p);
|
||||
}
|
||||
@@ -1811,7 +1811,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
|
||||
paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
|
||||
if( paNew==0 ) return SQLITE_NOMEM_BKPT;
|
||||
memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
|
||||
if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
|
||||
if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
|
||||
p->aLTerm = paNew;
|
||||
p->nLSlot = n;
|
||||
return SQLITE_OK;
|
||||
@@ -1841,7 +1841,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
|
||||
*/
|
||||
static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
|
||||
whereLoopClear(db, p);
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1862,7 +1862,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
|
||||
pWInfo->pLoops = p->pNextLoop;
|
||||
whereLoopDelete(db, p);
|
||||
}
|
||||
sqlite3DbFree(db, pWInfo);
|
||||
sqlite3DbFreeNN(db, pWInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3253,7 +3253,7 @@ static int whereLoopAddVirtual(
|
||||
}
|
||||
|
||||
if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
|
||||
sqlite3DbFree(pParse->db, p);
|
||||
sqlite3DbFreeNN(pParse->db, p);
|
||||
return rc;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
@@ -4108,7 +4108,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
|
||||
if( nFrom==0 ){
|
||||
sqlite3ErrorMsg(pParse, "no query solution");
|
||||
sqlite3DbFree(db, pSpace);
|
||||
sqlite3DbFreeNN(db, pSpace);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
@@ -4184,7 +4184,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
pWInfo->nRowOut = pFrom->nRow;
|
||||
|
||||
/* Free temporary memory and return success */
|
||||
sqlite3DbFree(db, pSpace);
|
||||
sqlite3DbFreeNN(db, pSpace);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -4262,7 +4262,8 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
|
||||
if( pLoop->wsFlags ){
|
||||
pLoop->nOut = (LogEst)1;
|
||||
pWInfo->a[0].pWLoop = pLoop;
|
||||
pLoop->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
|
||||
assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] );
|
||||
pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
|
||||
pWInfo->a[0].iTabCur = iCur;
|
||||
pWInfo->nRowOut = 1;
|
||||
if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix insert4
|
||||
|
||||
ifcapable !view||!subquery {
|
||||
finish_test
|
||||
@@ -566,4 +567,36 @@ do_catchsql_test insert4-9.1 {
|
||||
INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0;
|
||||
} {1 {no such collation sequence: xyzzy}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that running an integrity-check does not disable the xfer
|
||||
# optimization for tables with CHECK constraints.
|
||||
#
|
||||
do_execsql_test 10.1 {
|
||||
CREATE TABLE t8(
|
||||
rid INTEGER,
|
||||
pid INTEGER,
|
||||
mid INTEGER,
|
||||
px INTEGER DEFAULT(0) CHECK(px IN(0, 1))
|
||||
);
|
||||
CREATE TEMP TABLE x(
|
||||
rid INTEGER,
|
||||
pid INTEGER,
|
||||
mid INTEGER,
|
||||
px INTEGER DEFAULT(0) CHECK(px IN(0, 1))
|
||||
);
|
||||
}
|
||||
do_test 10.2 {
|
||||
set sqlite3_xferopt_count 0
|
||||
execsql { INSERT INTO x SELECT * FROM t8 }
|
||||
set sqlite3_xferopt_count
|
||||
} {1}
|
||||
|
||||
do_test 10.3 {
|
||||
execsql { PRAGMA integrity_check }
|
||||
set sqlite3_xferopt_count 0
|
||||
execsql { INSERT INTO x SELECT * FROM t8 }
|
||||
set sqlite3_xferopt_count
|
||||
} {1}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -298,4 +298,25 @@ for {set i 0} {$i<100} {incr i} {
|
||||
} {1}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# 2017-04-08 ticket b93be8729a895a528e2849fca99f7
|
||||
# JSON extension accepts invalid numeric values
|
||||
#
|
||||
# JSON does not allow leading zeros. But the JSON extension was
|
||||
# allowing them. The following tests verify that the problem is now
|
||||
# fixed.
|
||||
#
|
||||
do_execsql_test json102-1401 { SELECT json_valid('{"x":01}') } 0
|
||||
do_execsql_test json102-1402 { SELECT json_valid('{"x":-01}') } 0
|
||||
do_execsql_test json102-1403 { SELECT json_valid('{"x":0}') } 1
|
||||
do_execsql_test json102-1404 { SELECT json_valid('{"x":-0}') } 1
|
||||
do_execsql_test json102-1405 { SELECT json_valid('{"x":0.1}') } 1
|
||||
do_execsql_test json102-1406 { SELECT json_valid('{"x":-0.1}') } 1
|
||||
do_execsql_test json102-1407 { SELECT json_valid('{"x":0.0000}') } 1
|
||||
do_execsql_test json102-1408 { SELECT json_valid('{"x":-0.0000}') } 1
|
||||
do_execsql_test json102-1409 { SELECT json_valid('{"x":01.5}') } 0
|
||||
do_execsql_test json102-1410 { SELECT json_valid('{"x":-01.5}') } 0
|
||||
do_execsql_test json102-1411 { SELECT json_valid('{"x":00}') } 0
|
||||
do_execsql_test json102-1412 { SELECT json_valid('{"x":-00}') } 0
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# 2010 June 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix pragmafault
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
sqlite3_db_config_lookaside db 0 0 0
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, CHECK(a!=b));
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
catchsql { PRAGMA integrity_check }
|
||||
set {} 0
|
||||
} -test {
|
||||
faultsim_test_result {0 0}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,121 @@
|
||||
# 2016 December 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test the shell tool ".lint fkey-indexes" command.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !vtab {finish_test; return}
|
||||
set testprefix shell6
|
||||
set CLI [test_find_cli]
|
||||
db close
|
||||
forcedelete test.db test.db-journal test.db-wal
|
||||
|
||||
foreach {tn schema output} {
|
||||
1 {
|
||||
CREATE TABLE p1(a PRIMARY KEY, b);
|
||||
CREATE TABLE c1(x, y REFERENCES p1);
|
||||
} {
|
||||
CREATE INDEX 'c1_y' ON 'c1'('y'); --> p1(a)
|
||||
}
|
||||
|
||||
2 {
|
||||
CREATE TABLE p1(a PRIMARY KEY, b);
|
||||
CREATE TABLE c2(x REFERENCES p1, y REFERENCES p1);
|
||||
} {
|
||||
CREATE INDEX 'c2_y' ON 'c2'('y'); --> p1(a)
|
||||
CREATE INDEX 'c2_x' ON 'c2'('x'); --> p1(a)
|
||||
}
|
||||
|
||||
3 {
|
||||
CREATE TABLE 'p 1'(a, b, c, PRIMARY KEY(c, b));
|
||||
CREATE TABLE 'c 1'(x, y, z, FOREIGN KEY (z, y) REFERENCES 'p 1');
|
||||
} {
|
||||
CREATE INDEX 'c 1_z_y' ON 'c 1'('z', 'y'); --> p 1(c,b)
|
||||
}
|
||||
|
||||
4 {
|
||||
CREATE TABLE p1(a, 'b b b' PRIMARY KEY);
|
||||
CREATE TABLE c1('x y z' REFERENCES p1);
|
||||
CREATE INDEX i1 ON c1('x y z') WHERE "x y z" IS NOT NULL;
|
||||
} {
|
||||
}
|
||||
|
||||
5 {
|
||||
CREATE TABLE p1(a, 'b b b' PRIMARY KEY);
|
||||
CREATE TABLE c1('x y z' REFERENCES p1);
|
||||
CREATE INDEX i1 ON c1('x y z') WHERE "x y z" IS NOT 12;
|
||||
} {
|
||||
CREATE INDEX 'c1_x y z' ON 'c1'('x y z'); --> p1(b b b)
|
||||
}
|
||||
|
||||
6 {
|
||||
CREATE TABLE x1(a, b, c, UNIQUE(a, b));
|
||||
CREATE TABLE y1(a, b, c, FOREIGN KEY(b, a) REFERENCES x1(a, b));
|
||||
CREATE INDEX y1i ON y1(a, c, b);
|
||||
} {
|
||||
CREATE INDEX 'y1_b_a' ON 'y1'('b', 'a'); --> x1(a,b)
|
||||
}
|
||||
|
||||
6 {
|
||||
CREATE TABLE x1(a COLLATE nocase, b, UNIQUE(a));
|
||||
CREATE TABLE y1(a COLLATE rtrim REFERENCES x1(a));
|
||||
} {
|
||||
CREATE INDEX 'y1_a' ON 'y1'('a' COLLATE nocase); --> x1(a)
|
||||
}
|
||||
|
||||
7 {
|
||||
CREATE TABLE x1(a PRIMARY KEY COLLATE nocase, b);
|
||||
CREATE TABLE y1(a REFERENCES x1);
|
||||
} {
|
||||
CREATE INDEX 'y1_a' ON 'y1'('a' COLLATE nocase); --> x1(a)
|
||||
}
|
||||
|
||||
8 {
|
||||
CREATE TABLE x1(a, b COLLATE nocase, c COLLATE rtrim, PRIMARY KEY(c, b, a));
|
||||
CREATE TABLE y1(d, e, f, FOREIGN KEY(d, e, f) REFERENCES x1);
|
||||
} {
|
||||
CREATE INDEX 'y1_d_e_f' ON 'y1'('d' COLLATE rtrim, 'e' COLLATE nocase, 'f'); --> x1(c,b,a)
|
||||
}
|
||||
|
||||
9 {
|
||||
CREATE TABLE p1(a, b UNIQUE);
|
||||
CREATE TABLE c1(x INTEGER PRIMARY KEY REFERENCES p1(b));
|
||||
} {
|
||||
}
|
||||
|
||||
} {
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
execsql $schema
|
||||
|
||||
set expected ""
|
||||
foreach line [split $output "\n"] {
|
||||
set line [string trim $line]
|
||||
if {$line!=""} {
|
||||
append expected "$line\n"
|
||||
}
|
||||
}
|
||||
|
||||
do_test 1.$tn.1 {
|
||||
set RES [catchcmd test.db [list .lint fkey-indexes]]
|
||||
} [list 0 [string trim $expected]]
|
||||
|
||||
do_test 1.$tn.2 {
|
||||
execsql [lindex $RES 1]
|
||||
catchcmd test.db [list .lint fkey-indexes]
|
||||
} {0 {}}
|
||||
|
||||
db close
|
||||
}
|
||||
|
||||
finish_test
|
||||
+1
-1
@@ -22,7 +22,7 @@ set testprefix sync2
|
||||
# enabled. Also, since every test uses an ATTACHed database, they
|
||||
# are only run when ATTACH is enabled.
|
||||
#
|
||||
ifcapable !pager_pragmas||!attach {
|
||||
ifcapable !pager_pragmas||!attach||!dirsync {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ set pragma_def {
|
||||
FLAG: Result0
|
||||
|
||||
NAME: optimize
|
||||
FLAG: Result1
|
||||
FLAG: Result1 NeedSchema
|
||||
}
|
||||
|
||||
# Open the output file
|
||||
|
||||
Reference in New Issue
Block a user