/* Check that off_t can represent 2**63 - 1 correctly.
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
int
main ()
@@ -11449,19 +11459,10 @@
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
-
-########
-# The --enable-extensions argument is short-hand to enable
-# multiple extensions.
-# Check whether --enable-all was given.
-if test "${enable_all+set}" = set; then :
- enableval=$enable_all;
-fi
-
#########
# See whether we should enable Full Text Search extensions
# Check whether --enable-fts3 was given.
if test "${enable_fts3+set}" = set; then :
@@ -11474,11 +11475,11 @@
# Check whether --enable-fts4 was given.
if test "${enable_fts4+set}" = set; then :
enableval=$enable_fts4;
fi
-if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_fts4}" = "yes" ; then
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 :
$as_echo_n "(cached) " >&6
@@ -11538,11 +11539,11 @@
# Check whether --enable-fts5 was given.
if test "${enable_fts5+set}" = set; then :
enableval=$enable_fts5;
fi
-if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_fts5}" = "yes" ; then
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 :
$as_echo_n "(cached) " >&6
@@ -11605,11 +11606,11 @@
# Check whether --enable-json1 was given.
if test "${enable_json1+set}" = set; then :
enableval=$enable_json1;
fi
-if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_json1}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
fi
#########
# See whether we should enable the LIMIT clause on UPDATE and DELETE
@@ -11630,11 +11631,11 @@
enableval=$enable_geopoly; enable_geopoly=yes
else
enable_geopoly=no
fi
-if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_geopoly}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
enable_rtree=yes
fi
#########
@@ -11653,11 +11654,11 @@
# Check whether --enable-session was given.
if test "${enable_session+set}" = set; then :
enableval=$enable_session;
fi
-if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_session}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
fi
#########
@@ -12241,11 +12242,11 @@
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by sqlite $as_me 3.31.0, which was
+This file was extended by sqlite $as_me 3.28.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
@@ -12307,11 +12308,11 @@
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-sqlite config.status 3.31.0
+sqlite config.status 3.28.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
Index: configure.ac
==================================================================
--- configure.ac
+++ configure.ac
@@ -611,40 +611,34 @@
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
-########
-# The --enable-extensions argument is short-hand to enable
-# multiple extensions.
-AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all],
- [Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions]))
-
#########
# See whether we should enable Full Text Search extensions
AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
[Enable the FTS3 extension]))
if test "${enable_fts3}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
fi
AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
[Enable the FTS4 extension]))
-if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_fts4}" = "yes" ; then
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]))
-if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_fts5}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
AC_SEARCH_LIBS([log],[m])
fi
#########
# See whether we should enable JSON1
AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],[Enable the JSON1 extension]))
-if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_json1}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
fi
#########
# See whether we should enable the LIMIT clause on UPDATE and DELETE
@@ -658,11 +652,11 @@
#########
# See whether we should enable GEOPOLY
AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly],
[Enable the GEOPOLY extension]),
[enable_geopoly=yes],[enable_geopoly=no])
-if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_geopoly}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
enable_rtree=yes
fi
#########
@@ -675,11 +669,11 @@
#########
# See whether we should enable the SESSION extension
AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session],
[Enable the SESSION extension]))
-if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then
+if test "${enable_session}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
fi
#########
DELETED doc/trusted-schema.md
Index: doc/trusted-schema.md
==================================================================
--- doc/trusted-schema.md
+++ /dev/null
@@ -1,142 +0,0 @@
-# The new-security-options branch
-
-## The problem that the [new-security-options](/timeline?r=new-security-options) branch tries to solve
-
-An attacker might modify the schema of an SQLite database by adding
-structures that cause code to run when some other application opens and
-reads the database. For example, the attacker might replace a table
-definition with a view. Or the attacker might add triggers to tables
-or views, or add new CHECK constraints or generated columns or indexes
-with expressions in the index list or in the WHERE clause. If the
-added features invoke SQL functions or virtual tables with side effects,
-that might cause harm to the system if run by a high-privilege victim.
-Or, the added features might exfiltrate information if the database is
-read by a high-privilege victim.
-
-The changes in this branch strive to make it easier for high-privilege
-applications to safely read SQLite database files that might have been
-maliciously corrupted by an attacker.
-
-## Overview of changes in [new-security-options](/timeline?r=new-security-options)
-
-The basic idea is to tag every SQL function and virtual table with one
-of three risk levels:
-
- 1. Innocuous
- 2. Normal
- 3. Direct-Only
-
-Innocuous functions/vtabs are safe and can be used at any time.
-Direct-only elements, in contrast, might have cause side-effects and
-should only be used from top-level SQL, not from within triggers or views nor
-in elements of the schema such as CHECK constraint, DEFAULT values,
-generated columns, index expressions, or in the WHERE clause of a
-partial index that are potentially under the control of an attacker.
-Normal elements behave like Innocuous if TRUSTED\_SCHEMA=on
-and behave like direct-only if TRUSTED\_SCHEMA=off.
-
-Application-defined functions and virtual tables go in as Normal unless
-the application takes deliberate steps to change the risk level.
-
-For backwards compatibility, the default is TRUSTED\_SCHEMA=on. Documentation
-will be updated to recommend applications turn TRUSTED\_SCHEMA to off.
-
-An innocuous function or virtual table is one that can only read content
-from the database file in which it resides, and can only alter the database
-in which it resides. Most SQL functions are innocuous. For example, there
-is no harm in an attacker running the abs() function.
-
-Direct-only elements that have side-effects that go outside the database file
-in which it lives, or return information from outside of the database file.
-Examples of direct-only elements include:
-
- 1. The fts3\_tokenizer() function
- 2. The writefile() function
- 3. The readfile() function
- 4. The zipvfs virtual table
- 5. The csv virtual table
-
-We do not want an attacker to be able to add these kinds of things to
-the database schema and possibly trick a high-privilege application
-from performing any of these actions. Therefore, functions and vtabs
-with side-effects are marked as Direct-Only.
-
-Legacy applications might add other risky functions or vtabs. Those will
-go in as "Normal" by default. For optimal security, we want those risky
-app-defined functions and vtabs to be direct-only, but making that the
-default might break some legacy applications. Hence, all app-defined
-functions and vtabs go in as Normal, but the application can switch them
-over to "Direct-Only" behavior using a single pragma.
-
-The restrictions on the use of functions and virtual tables do not apply
-to TEMP. A TEMP VIEW or a TEMP TRIGGER can use any valid SQL function
-or virtual table. The idea is that TEMP views and triggers must be
-directly created by the application and are thus under the control of the
-application. TEMP views and triggers cannot be created by an attacker who
-corrupts the schema of a persistent database file. Hence TEMP views and
-triggers are safe.
-
-## Specific changes
-
- 1. New sqlite3\_db\_config() option SQLITE\_DBCONFIG\_TRUSTED\_SCHEMA for
- turning TRUSTED\_SCHEMA on and off. It defaults to ON.
-
- 2. Compile-time option -DSQLITE\_TRUSTED\_SCHEMA=0 causes the default
- TRUSTED\_SCHEMA setting to be off.
-
- 3. New pragma "PRAGMA trusted\_schema=(ON\|OFF);". This provides access
- to the TRUSTED_SCHEMA setting for application coded using scripting
- languages or other secondary languages where they are unable to make
- calls to sqlite3\_db\_config().
-
- 4. New options for the "enc" parameter to sqlite3\_create\_function() and
- its kin:
-
- - _SQLITE\_INNOCUOUS_ → tags the new functions as Innocuous
-
- _SQLITE\_DIRECTONLY_ → tags the new functions as Direct-Only
-
-
- 5. New options to sqlite3\_vtab\_config():
-
- - _SQLITE\_VTAB\_INNOCUOUS_ → tags the vtab as Innocuous
-
- _SQLITE\_VTAB\_DIRECTONLY_ → tags the vtab as Direct-Only
-
-
- 6. Change many of the functions and virtual tables in the SQLite source
- tree to use one of the tags above.
-
- 7. Enhanced PRAGMA function\_list and virtual-table "pragma\_function\_list"
- with additional columns. The columns now are:
-
- - _name_ → Name of the function
-
- _builtin_ → 1 for built-in functions. 0 otherwise.
-
- _type_ → 's'=Scalar, 'a'=Aggregate, 'w'=Window
-
- _enc_ → 'utf8', 'utf16le', or 'utf16be'
-
- _narg_ → number of argument
-
- _flags_ → Bitmask of SQLITE\_INNOCUOUS, SQLITE\_DIRECTONLY,
- SQLITE\_DETERMINISTIC, SQLITE\_SUBTYPE, and
- SQLITE\_FUNC\_INTERNAL flags.
-
- The last four columns are new.
-
- 8. The function\_list PRAGMA now also shows all entries for each function.
- So, for example, if a function can take either 2 or 3 arguments,
- there are separate rows for the 2-argument and 3-argument versions of
- the function.
-
-## Additional Notes
-
-The function_list enhancements allow the application to query the set
-of SQL functions that meet various criteria. For example, to see all
-SQL functions that are never allowed to be used in the schema or in
-trigger or views:
-
-~~~
- SELECT DISTINCT name FROM pragma_function_list
- WHERE (flags & 0x80000)!=0
- ORDER BY name;
-~~~
-
-Doing the same is not possible for virtual tables, as a virtual table
-might be Innocuous, Normal, or Direct-Only depending on the arguments
-passed into the xConnect method.
Index: ext/expert/expert1.test
==================================================================
--- ext/expert/expert1.test
+++ ext/expert/expert1.test
@@ -132,19 +132,17 @@
} {
CREATE INDEX t1_idx_000123a7 ON t1(a, b);
SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
}
-if 0 {
do_setup_rec_test $tn.6 {
CREATE TABLE t1(a, b, c);
} {
SELECT min(a) FROM t1
} {
CREATE INDEX t1_idx_00000061 ON t1(a);
SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
-}
}
do_setup_rec_test $tn.7 {
CREATE TABLE t1(a, b, c);
} {
Index: ext/expert/sqlite3expert.h
==================================================================
--- ext/expert/sqlite3expert.h
+++ ext/expert/sqlite3expert.h
@@ -8,12 +8,12 @@
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
*/
-#if !defined(SQLITEEXPERT_H)
-#define SQLITEEXPERT_H 1
+
+
#include "sqlite3.h"
typedef struct sqlite3expert sqlite3expert;
/*
@@ -163,6 +163,6 @@
** should be one call to this function for each successful call to
** sqlite3-expert_new().
*/
void sqlite3_expert_destroy(sqlite3expert*);
-#endif /* !defined(SQLITEEXPERT_H) */
+
Index: ext/fts5/fts5.h
==================================================================
--- ext/fts5/fts5.h
+++ ext/fts5/fts5.h
@@ -157,11 +157,11 @@
** the callback, an SQLite error code is returned.
**
**
** xSetAuxdata(pFts5, pAux, xDelete)
**
-** Save the pointer passed as the second argument as the extension function's
+** Save the pointer passed as the second argument as the extension functions
** "auxiliary data". The pointer may then be retrieved by the current or any
** future invocation of the same fts5 extension function made as part of
** the same MATCH query using the xGetAuxdata() API.
**
** Each extension function is allocated a single auxiliary data slot for
@@ -399,12 +399,12 @@
** all instances of "first place" or "1st place" regardless of which form
** the user specified in the MATCH query text.
**
** There are several ways to approach this in FTS5:
**
-**
- By mapping all synonyms to a single token. In this case, using
-** the above example, this means that the tokenizer returns the
+**
- By mapping all synonyms to a single token. In this case, the
+** In the above example, this means that the tokenizer returns the
** same token for inputs "first" and "1st". Say that token is in
** fact "first", so that when the user inserts the document "I won
** 1st place" entries are added to the index for tokens "i", "won",
** "first" and "place". If the user then queries for '1st + place',
** the tokenizer substitutes "first" for "1st" and the query works
Index: ext/fts5/fts5Int.h
==================================================================
--- ext/fts5/fts5Int.h
+++ ext/fts5/fts5Int.h
@@ -59,15 +59,10 @@
** less than 32. If it is set to anything large than that, an #error
** directive in fts5_index.c will cause the build to fail.
*/
#define FTS5_MAX_PREFIX_INDEXES 31
-/*
-** Maximum segments permitted in a single index
-*/
-#define FTS5_MAX_SEGMENT 2000
-
#define FTS5_DEFAULT_NEARDIST 10
#define FTS5_DEFAULT_RANK "bm25"
/* Name of rank and rowid columns */
#define FTS5_RANK_NAME "rank"
@@ -181,11 +176,10 @@
int bColumnsize; /* "columnsize=" option value (dflt==1) */
int eDetail; /* FTS5_DETAIL_XXX value */
char *zContentExprlist;
Fts5Tokenizer *pTok;
fts5_tokenizer *pTokApi;
- int bLock; /* True when table is preparing statement */
/* Values loaded from the %_config table */
int iCookie; /* Incremented when %_config is modified */
int pgsz; /* Approximate page size used in %_data */
int nAutomerge; /* 'automerge' setting */
@@ -420,15 +414,10 @@
/*
** Close an iterator opened by sqlite3Fts5IndexQuery().
*/
void sqlite3Fts5IterClose(Fts5IndexIter*);
-/*
-** Close the reader blob handle, if it is open.
-*/
-void sqlite3Fts5IndexCloseReader(Fts5Index*);
-
/*
** This interface is used by the fts5vocab module.
*/
const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*);
int sqlite3Fts5IterNextScan(Fts5IndexIter*);
@@ -703,11 +692,10 @@
int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
int sqlite3Fts5ExprEof(Fts5Expr*);
i64 sqlite3Fts5ExprRowid(Fts5Expr*);
void sqlite3Fts5ExprFree(Fts5Expr*);
-int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2);
/* Called during startup to register a UDF with SQLite */
int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);
int sqlite3Fts5ExprPhraseCount(Fts5Expr*);
Index: ext/fts5/fts5_buffer.c
==================================================================
--- ext/fts5/fts5_buffer.c
+++ ext/fts5/fts5_buffer.c
@@ -176,23 +176,14 @@
return 1;
}else{
i64 iOff = *piOff;
int iVal;
fts5FastGetVarint32(a, i, iVal);
- if( iVal<=1 ){
- if( iVal==0 ){
- *pi = i;
- return 0;
- }
+ if( iVal==1 ){
fts5FastGetVarint32(a, i, iVal);
iOff = ((i64)iVal) << 32;
fts5FastGetVarint32(a, i, iVal);
- if( iVal<2 ){
- /* This is a corrupt record. So stop parsing it here. */
- *piOff = -1;
- return 1;
- }
}
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
*pi = i;
return 0;
}
Index: ext/fts5/fts5_config.c
==================================================================
--- ext/fts5/fts5_config.c
+++ ext/fts5/fts5_config.c
@@ -21,11 +21,11 @@
#define FTS5_DEFAULT_USERMERGE 4
#define FTS5_DEFAULT_CRISISMERGE 16
#define FTS5_DEFAULT_HASHSIZE (1024*1024)
/* Maximum allowed page size */
-#define FTS5_MAX_PAGE_SIZE (64*1024)
+#define FTS5_MAX_PAGE_SIZE (128*1024)
static int fts5_iswhitespace(char x){
return (x==' ');
}
@@ -148,11 +148,11 @@
/* Set stack variable q to the close-quote character */
assert( q=='[' || q=='\'' || q=='"' || q=='`' );
if( q=='[' ) q = ']';
- while( z[iIn] ){
+ while( ALWAYS(z[iIn]) ){
if( z[iIn]==q ){
if( z[iIn+1]!=q ){
/* Character iIn was the close quote. */
iIn++;
break;
@@ -681,11 +681,11 @@
assert( zSql || rc==SQLITE_NOMEM );
if( zSql ){
rc = sqlite3_declare_vtab(pConfig->db, zSql);
sqlite3_free(zSql);
}
-
+
return rc;
}
/*
** Tokenize the text passed via the second and third arguments.
@@ -826,11 +826,11 @@
if( 0==sqlite3_stricmp(zKey, "pgsz") ){
int pgsz = 0;
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
pgsz = sqlite3_value_int(pVal);
}
- if( pgsz<32 || pgsz>FTS5_MAX_PAGE_SIZE ){
+ if( pgsz<=0 || pgsz>FTS5_MAX_PAGE_SIZE ){
*pbBadkey = 1;
}else{
pConfig->pgsz = pgsz;
}
}
@@ -879,11 +879,10 @@
}
if( nCrisisMerge<0 ){
*pbBadkey = 1;
}else{
if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
- if( nCrisisMerge>=FTS5_MAX_SEGMENT ) nCrisisMerge = FTS5_MAX_SEGMENT-1;
pConfig->nCrisisMerge = nCrisisMerge;
}
}
else if( 0==sqlite3_stricmp(zKey, "rank") ){
Index: ext/fts5/fts5_expr.c
==================================================================
--- ext/fts5/fts5_expr.c
+++ ext/fts5/fts5_expr.c
@@ -307,46 +307,10 @@
sqlite3_free(p->apExprPhrase);
sqlite3_free(p);
}
}
-int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
- Fts5Parse sParse;
- memset(&sParse, 0, sizeof(sParse));
-
- if( *pp1 ){
- Fts5Expr *p1 = *pp1;
- int nPhrase = p1->nPhrase + p2->nPhrase;
-
- p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0);
- p2->pRoot = 0;
-
- if( sParse.rc==SQLITE_OK ){
- Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc(
- p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*)
- );
- if( ap==0 ){
- sParse.rc = SQLITE_NOMEM;
- }else{
- int i;
- memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*));
- for(i=0; inPhrase; i++){
- ap[i] = p2->apExprPhrase[i];
- }
- p1->nPhrase = nPhrase;
- p1->apExprPhrase = ap;
- }
- }
- sqlite3_free(p2->apExprPhrase);
- sqlite3_free(p2);
- }else{
- *pp1 = p2;
- }
-
- return sParse.rc;
-}
-
/*
** Argument pTerm must be a synonym iterator. Return the current rowid
** that it points to.
*/
static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
@@ -2514,16 +2478,14 @@
}
azConfig[0] = 0;
azConfig[1] = "main";
azConfig[2] = "tbl";
for(i=3; iArgnCol, zExpr, &pExpr, &zErr);
}
Index: ext/fts5/fts5_index.c
==================================================================
--- ext/fts5/fts5_index.c
+++ ext/fts5/fts5_index.c
@@ -237,10 +237,15 @@
)
#define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno)
#define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)
+/*
+** Maximum segments permitted in a single index
+*/
+#define FTS5_MAX_SEGMENT 2000
+
#ifdef SQLITE_DEBUG
int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
#endif
@@ -612,11 +617,11 @@
}
/*
** Close the read-only blob handle, if it is open.
*/
-void sqlite3Fts5IndexCloseReader(Fts5Index *p){
+static void fts5CloseReader(Fts5Index *p){
if( p->pReader ){
sqlite3_blob *pReader = p->pReader;
p->pReader = 0;
sqlite3_blob_close(pReader);
}
@@ -641,11 +646,11 @@
p->pReader = 0;
rc = sqlite3_blob_reopen(pBlob, iRowid);
assert( p->pReader==0 );
p->pReader = pBlob;
if( rc!=SQLITE_OK ){
- sqlite3Fts5IndexCloseReader(p);
+ fts5CloseReader(p);
}
if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
}
/* If the blob handle is not open at this point, open it and seek
@@ -683,11 +688,10 @@
sqlite3_free(pRet);
pRet = 0;
}else{
/* TODO1: Fix this */
pRet->p[nByte] = 0x00;
- pRet->p[nByte+1] = 0x00;
pRet->szLeaf = fts5GetU16(&pRet->p[2]);
}
}
p->rc = rc;
p->nRead++;
@@ -706,11 +710,11 @@
}
static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
Fts5Data *pRet = fts5DataRead(p, iRowid);
if( pRet ){
- if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){
+ if( pRet->szLeaf>pRet->nn ){
p->rc = FTS5_CORRUPT;
fts5DataRelease(pRet);
pRet = 0;
}
}
@@ -986,11 +990,11 @@
pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
if( p->rc==SQLITE_OK ){
/* TODO: Do we need this if the leaf-index is appended? Probably... */
memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
- if( p->rc==SQLITE_OK && (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
+ if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
}
fts5DataRelease(pData);
if( p->rc!=SQLITE_OK ){
fts5StructureRelease(pRet);
@@ -4947,18 +4951,12 @@
/* The maximum size of the output is equal to the sum of the two
** input sizes + 1 varint (9 bytes). The extra varint is because if the
** first rowid in one input is a large negative number, and the first in
** the other a non-negative number, the delta for the non-negative
** number will be larger on disk than the literal integer value
- ** was.
- **
- ** Or, if the input position-lists are corrupt, then the output might
- ** include up to 2 extra 10-byte positions created by interpreting -1
- ** (the value PoslistNext64() uses for EOF) as a position and appending
- ** it to the output. This can happen at most once for each input
- ** position-list, hence two 10 byte paddings. */
- if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return;
+ ** was. */
+ if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
fts5DoclistIterInit(p1, &i1);
fts5DoclistIterInit(p2, &i2);
while( 1 ){
if( i1.iRowidp) + (i2.aPoslist-p2->p)+9+10+10) );
}
else if( i2.iRowid!=i1.iRowid ){
/* Copy entry from i2 */
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
fts5DoclistIterNext(&i2);
if( i2.aPoslist==0 ) break;
- assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
}
else{
/* Merge the two position lists. */
i64 iPos1 = 0;
i64 iPos2 = 0;
@@ -4990,29 +4986,27 @@
i64 iPrev = 0;
Fts5PoslistWriter writer;
memset(&writer, 0, sizeof(writer));
- /* See the earlier comment in this function for an explanation of why
- ** corrupt input position lists might cause the output to consume
- ** at most 20 bytes of unexpected space. */
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
fts5BufferZero(&tmp);
- sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10);
+ sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist);
if( p->rc ) break;
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
- assert_nc( iPos1>=0 && iPos2>=0 );
+ assert( iPos1>=0 && iPos2>=0 );
if( iPos1=0 && iPos2>=0 ){
while( 1 ){
if( iPos1=0 && iPos2!=iPrev );
+ assert( iPos2>=0 && iPos2!=iPrev );
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
aCopy = &a2[iOff2];
nCopy = i2.nPoslist - iOff2;
}
if( nCopy>0 ){
fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy);
}
/* WRITEPOSLISTSIZE */
- assert_nc( tmp.n<=i1.nPoslist+i2.nPoslist );
- assert( tmp.n<=i1.nPoslist+i2.nPoslist+10+10 );
- if( tmp.n>i1.nPoslist+i2.nPoslist ){
- if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
- break;
- }
fts5BufferSafeAppendVarint(&out, tmp.n * 2);
fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
fts5DoclistIterNext(&i1);
fts5DoclistIterNext(&i2);
- assert_nc( out.n<=(p1->n+p2->n+9) );
+ assert( out.n<=(p1->n+p2->n+9) );
if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
- assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
}
}
if( i1.aPoslist ){
fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
@@ -5067,11 +5054,11 @@
}
else if( i2.aPoslist ){
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
}
- assert_nc( out.n<=(p1->n+p2->n+9) );
+ assert( out.n<=(p1->n+p2->n+9) );
fts5BufferSet(&p->rc, p1, out.n, out.p);
fts5BufferFree(&tmp);
fts5BufferFree(&out);
}
@@ -5202,11 +5189,11 @@
** Commit data to disk.
*/
int sqlite3Fts5IndexSync(Fts5Index *p){
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
- sqlite3Fts5IndexCloseReader(p);
+ fts5CloseReader(p);
return fts5IndexReturn(p);
}
/*
** Discard any data stored in the in-memory hash tables. Do not write it
@@ -5213,11 +5200,11 @@
** to the database. Additionally, assume that the contents of the %_data
** table may have changed on disk. So any in-memory caches of %_data
** records must be invalidated.
*/
int sqlite3Fts5IndexRollback(Fts5Index *p){
- sqlite3Fts5IndexCloseReader(p);
+ fts5CloseReader(p);
fts5IndexDiscardData(p);
fts5StructureInvalidate(p);
/* assert( p->rc==SQLITE_OK ); */
return SQLITE_OK;
}
@@ -5228,11 +5215,10 @@
** and the initial version of the "averages" record (a zero-byte blob).
*/
int sqlite3Fts5IndexReinit(Fts5Index *p){
Fts5Structure s;
fts5StructureInvalidate(p);
- fts5IndexDiscardData(p);
memset(&s, 0, sizeof(Fts5Structure));
fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
fts5StructureWrite(p, &s);
return fts5IndexReturn(p);
}
@@ -5316,17 +5302,13 @@
int n = 0;
int i;
for(i=0; i=nByte ) return 0; /* Input contains fewer than nChar chars */
if( (unsigned char)p[n++]>=0xc0 ){
- if( n>=nByte ) return 0;
while( (p[n] & 0xc0)==0x80 ){
n++;
- if( n>=nByte ){
- if( i+1==nChar ) break;
- return 0;
- }
+ if( n>=nByte ) break;
}
}
}
return n;
}
@@ -5458,11 +5440,11 @@
}
if( p->rc ){
sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
pRet = 0;
- sqlite3Fts5IndexCloseReader(p);
+ fts5CloseReader(p);
}
*ppIter = (Fts5IndexIter*)pRet;
sqlite3Fts5BufferFree(&buf);
}
@@ -5531,11 +5513,11 @@
void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
if( pIndexIter ){
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
Fts5Index *pIndex = pIter->pIndex;
fts5MultiIterFree(pIter);
- sqlite3Fts5IndexCloseReader(pIndex);
+ fts5CloseReader(pIndex);
}
}
/*
** Read and decode the "averages" record from the database.
@@ -5724,41 +5706,10 @@
*pCksum = cksum;
return rc;
}
-/*
-** Check if buffer z[], size n bytes, contains as series of valid utf-8
-** encoded codepoints. If so, return 0. Otherwise, if the buffer does not
-** contain valid utf-8, return non-zero.
-*/
-static int fts5TestUtf8(const char *z, int n){
- assert_nc( n>0 );
- int i = 0;
- while( i=n || (z[i+1] & 0xC0)!=0x80 ) return 1;
- i += 2;
- }else
- if( (z[i] & 0xF0)==0xE0 ){
- if( i+2>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1;
- i += 3;
- }else
- if( (z[i] & 0xF8)==0xF0 ){
- if( i+3>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1;
- if( (z[i+2] & 0xC0)!=0x80 ) return 1;
- i += 3;
- }else{
- return 1;
- }
- }
-
- return 0;
-}
/*
** This function is also purely an internal test. It does not contribute to
** FTS functionality, or even the integrity-check, in any way.
*/
@@ -5795,18 +5746,12 @@
** the index is disabled are the same. In both ASC and DESC order.
**
** This check may only be performed if the hash table is empty. This
** is because the hash table only supports a single scan query at
** a time, and the multi-iter loop from which this function is called
- ** is already performing such a scan.
- **
- ** Also only do this if buffer zTerm contains nTerm bytes of valid
- ** utf-8. Otherwise, the last part of the buffer contents might contain
- ** a non-utf-8 sequence that happens to be a prefix of a valid utf-8
- ** character stored in the main fts index, which will cause the
- ** test to fail. */
- if( p->nPendingData==0 && 0==fts5TestUtf8(zTerm, nTerm) ){
+ ** is already performing such a scan. */
+ if( p->nPendingData==0 ){
if( iIdx>0 && rc==SQLITE_OK ){
int f = flags|FTS5INDEX_QUERY_TEST_NOIDX;
ck2 = 0;
rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
@@ -5925,22 +5870,21 @@
int iDlidxPrevLeaf = pSeg->pgnoLast;
if( pSeg->pgnoFirst==0 ) return;
fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf(
- "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d "
- "ORDER BY 1, 2",
+ "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d",
pConfig->zDb, pConfig->zName, pSeg->iSegid
));
/* Iterate through the b-tree hierarchy. */
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
i64 iRow; /* Rowid for this leaf */
Fts5Data *pLeaf; /* Data for this leaf */
- const char *zIdxTerm = (const char*)sqlite3_column_blob(pStmt, 1);
int nIdxTerm = sqlite3_column_bytes(pStmt, 1);
+ const char *zIdxTerm = (const char*)sqlite3_column_text(pStmt, 1);
int iIdxLeaf = sqlite3_column_int(pStmt, 2);
int bIdxDlidx = sqlite3_column_int(pStmt, 3);
/* If the leaf in question has already been trimmed from the segment,
** ignore this b-tree entry. Otherwise, load it into memory. */
Index: ext/fts5/fts5_main.c
==================================================================
--- ext/fts5/fts5_main.c
+++ ext/fts5/fts5_main.c
@@ -287,14 +287,11 @@
break;
case FTS5_ROLLBACKTO:
assert( p->ts.eState==1 );
assert( iSavepoint>=-1 );
- /* The following assert() can fail if another vtab strikes an error
- ** within an xSavepoint() call then SQLite calls xRollbackTo() - without
- ** having called xSavepoint() on this vtab. */
- /* assert( iSavepoint<=p->ts.iSavepoint ); */
+ assert( iSavepoint<=p->ts.iSavepoint );
p->ts.iSavepoint = iSavepoint;
break;
}
}
#else
@@ -466,43 +463,21 @@
/*
** Implementation of the xBestIndex method for FTS5 tables. Within the
** WHERE constraint, it searches for the following:
**
-** 1. A MATCH constraint against the table column.
+** 1. A MATCH constraint against the special column.
** 2. A MATCH constraint against the "rank" column.
-** 3. A MATCH constraint against some other column.
-** 4. An == constraint against the rowid column.
-** 5. A < or <= constraint against the rowid column.
-** 6. A > or >= constraint against the rowid column.
+** 3. An == constraint against the rowid column.
+** 4. A < or <= constraint against the rowid column.
+** 5. A > or >= constraint against the rowid column.
**
-** Within the ORDER BY, the following are supported:
+** Within the ORDER BY, either:
**
** 5. ORDER BY rank [ASC|DESC]
** 6. ORDER BY rowid [ASC|DESC]
**
-** Information for the xFilter call is passed via both the idxNum and
-** idxStr variables. Specifically, idxNum is a bitmask of the following
-** flags used to encode the ORDER BY clause:
-**
-** FTS5_BI_ORDER_RANK
-** FTS5_BI_ORDER_ROWID
-** FTS5_BI_ORDER_DESC
-**
-** idxStr is used to encode data from the WHERE clause. For each argument
-** passed to the xFilter method, the following is appended to idxStr:
-**
-** Match against table column: "m"
-** Match against rank column: "r"
-** Match against other column: ""
-** Equality constraint against the rowid: "="
-** A < or <= against the rowid: "<"
-** A > or >= against the rowid: ">"
-**
-** This function ensures that there is at most one "r" or "=". And that if
-** there exists an "=" then there is no "<" or ">".
-**
** Costs are assigned as follows:
**
** a) If an unusable MATCH operator is present in the WHERE clause, the
** cost is unconditionally set to 1e50 (a really big number).
**
@@ -526,108 +501,77 @@
static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
Fts5Table *pTab = (Fts5Table*)pVTab;
Fts5Config *pConfig = pTab->pConfig;
const int nCol = pConfig->nCol;
int idxFlags = 0; /* Parameter passed through to xFilter() */
+ int bHasMatch;
+ int iNext;
int i;
- char *idxStr;
- int iIdxStr = 0;
- int iCons = 0;
-
- int bSeenEq = 0;
- int bSeenGt = 0;
- int bSeenLt = 0;
- int bSeenMatch = 0;
- int bSeenRank = 0;
-
+ struct Constraint {
+ int op; /* Mask against sqlite3_index_constraint.op */
+ int fts5op; /* FTS5 mask for idxFlags */
+ int iCol; /* 0==rowid, 1==tbl, 2==rank */
+ int omit; /* True to omit this if found */
+ int iConsIndex; /* Index in pInfo->aConstraint[] */
+ } aConstraint[] = {
+ {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
+ FTS5_BI_MATCH, 1, 1, -1},
+ {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
+ FTS5_BI_RANK, 2, 1, -1},
+ {SQLITE_INDEX_CONSTRAINT_EQ, FTS5_BI_ROWID_EQ, 0, 0, -1},
+ {SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE,
+ FTS5_BI_ROWID_LE, 0, 0, -1},
+ {SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE,
+ FTS5_BI_ROWID_GE, 0, 0, -1},
+ };
+
+ int aColMap[3];
+ aColMap[0] = -1;
+ aColMap[1] = nCol;
+ aColMap[2] = nCol+1;
assert( SQLITE_INDEX_CONSTRAINT_EQbLock ){
- pTab->base.zErrMsg = sqlite3_mprintf(
- "recursively defined fts5 content table"
- );
- return SQLITE_ERROR;
- }
-
- idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1);
- if( idxStr==0 ) return SQLITE_NOMEM;
- pInfo->idxStr = idxStr;
- pInfo->needToFreeIdxStr = 1;
-
+ /* Set idxFlags flags for all WHERE clause terms that will be used. */
for(i=0; inConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
int iCol = p->iColumn;
- if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH
- || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol)
+
+ if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
+ || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
){
/* A MATCH operator or equivalent */
- if( p->usable==0 || iCol<0 ){
+ if( p->usable ){
+ idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
+ aConstraint[0].iConsIndex = i;
+ }else{
/* As there exists an unusable MATCH constraint this is an
** unusable plan. Set a prohibitively high cost. */
pInfo->estimatedCost = 1e50;
- assert( iIdxStr < pInfo->nConstraint*6 + 1 );
- idxStr[iIdxStr] = 0;
return SQLITE_OK;
- }else{
- if( iCol==nCol+1 ){
- if( bSeenRank ) continue;
- idxStr[iIdxStr++] = 'r';
- bSeenRank = 1;
- }else{
- bSeenMatch = 1;
- idxStr[iIdxStr++] = 'm';
- if( iColaConstraintUsage[i].argvIndex = ++iCons;
- pInfo->aConstraintUsage[i].omit = 1;
- }
- }
- else if( p->usable && bSeenEq==0
- && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0
- ){
- idxStr[iIdxStr++] = '=';
- bSeenEq = 1;
- pInfo->aConstraintUsage[i].argvIndex = ++iCons;
- }
- }
-
- if( bSeenEq==0 ){
- for(i=0; inConstraint; i++){
- struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
- if( p->iColumn<0 && p->usable ){
- int op = p->op;
- if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){
- if( bSeenLt ) continue;
- idxStr[iIdxStr++] = '<';
- pInfo->aConstraintUsage[i].argvIndex = ++iCons;
- bSeenLt = 1;
- }else
- if( op==SQLITE_INDEX_CONSTRAINT_GT || op==SQLITE_INDEX_CONSTRAINT_GE ){
- if( bSeenGt ) continue;
- idxStr[iIdxStr++] = '>';
- pInfo->aConstraintUsage[i].argvIndex = ++iCons;
- bSeenGt = 1;
- }
- }
- }
- }
- idxStr[iIdxStr] = '\0';
+ }
+ }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){
+ int j;
+ for(j=1; jiCol] && (p->op & pC->op) && p->usable ){
+ pC->iConsIndex = i;
+ idxFlags |= pC->fts5op;
+ }
+ }
+ }
+ }
/* Set idxFlags flags for the ORDER BY clause */
if( pInfo->nOrderBy==1 ){
int iSort = pInfo->aOrderBy[0].iColumn;
- if( iSort==(pConfig->nCol+1) && bSeenMatch ){
+ if( iSort==(pConfig->nCol+1) && BitFlagTest(idxFlags, FTS5_BI_MATCH) ){
idxFlags |= FTS5_BI_ORDER_RANK;
}else if( iSort==-1 ){
idxFlags |= FTS5_BI_ORDER_ROWID;
}
if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
@@ -637,19 +581,30 @@
}
}
}
/* Calculate the estimated cost based on the flags set in idxFlags. */
- if( bSeenEq ){
- pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0;
- if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
- }else if( bSeenLt && bSeenGt ){
- pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0;
- }else if( bSeenLt || bSeenGt ){
- pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0;
+ bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH);
+ if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){
+ pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0;
+ if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo);
+ }else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
+ pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0;
+ }else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
+ pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0;
}else{
- pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0;
+ pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0;
+ }
+
+ /* Assign argvIndex values to each constraint in use. */
+ iNext = 1;
+ for(i=0; iiConsIndex>=0 ){
+ pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
+ pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
+ }
}
pInfo->idxNum = idxFlags;
return SQLITE_OK;
}
@@ -745,11 +700,10 @@
if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
sqlite3_free(pCsr->zRank);
sqlite3_free(pCsr->zRankArgs);
}
- sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr));
}
/*
@@ -896,28 +850,19 @@
case FTS5_PLAN_SORTED_MATCH: {
rc = fts5SorterNext(pCsr);
break;
}
- default: {
- Fts5Config *pConfig = ((Fts5Table*)pCursor->pVtab)->pConfig;
- pConfig->bLock++;
+ default:
rc = sqlite3_step(pCsr->pStmt);
- pConfig->bLock--;
if( rc!=SQLITE_ROW ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
rc = sqlite3_reset(pCsr->pStmt);
- if( rc!=SQLITE_OK ){
- pCursor->pVtab->zErrMsg = sqlite3_mprintf(
- "%s", sqlite3_errmsg(pConfig->db)
- );
- }
}else{
rc = SQLITE_OK;
}
break;
- }
}
}
return rc;
}
@@ -978,11 +923,11 @@
** And since the statement required here reads from this very virtual
** table, saving it creates a circular reference.
**
** If SQLite a built-in statement cache, this wouldn't be a problem. */
rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
- "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s",
+ "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
(zRankArgs ? ", " : ""),
(zRankArgs ? zRankArgs : ""),
bDesc ? "DESC" : "ASC"
);
@@ -1034,14 +979,14 @@
for(n=0; z[n] && z[n]!=' '; n++);
assert( pTab->p.base.zErrMsg==0 );
pCsr->ePlan = FTS5_PLAN_SPECIAL;
- if( n==5 && 0==sqlite3_strnicmp("reads", z, n) ){
+ if( 0==sqlite3_strnicmp("reads", z, n) ){
pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex);
}
- else if( n==2 && 0==sqlite3_strnicmp("id", z, n) ){
+ else if( 0==sqlite3_strnicmp("id", z, n) ){
pCsr->iSpecial = pCsr->iCsrId;
}
else{
/* An unrecognized directive. Return an error message. */
pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
@@ -1178,36 +1123,31 @@
** 3. A full-table scan.
*/
static int fts5FilterMethod(
sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
int idxNum, /* Strategy index */
- const char *idxStr, /* Unused */
+ const char *zUnused, /* Unused */
int nVal, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int rc = SQLITE_OK; /* Error code */
+ int iVal = 0; /* Counter for apVal[] */
int bDesc; /* True if ORDER BY [rank|rowid] DESC */
int bOrderByRank; /* True if ORDER BY rank */
+ sqlite3_value *pMatch = 0; /* MATCH ? expression (or NULL) */
sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */
sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
int iCol; /* Column on LHS of MATCH operator */
char **pzErrmsg = pConfig->pzErrmsg;
- int i;
- int iIdxStr = 0;
- Fts5Expr *pExpr = 0;
-
- if( pConfig->bLock ){
- pTab->p.base.zErrMsg = sqlite3_mprintf(
- "recursively defined fts5 content table"
- );
- return SQLITE_ERROR;
- }
+
+ UNUSED_PARAM(zUnused);
+ UNUSED_PARAM(nVal);
if( pCsr->ePlan ){
fts5FreeCursorComponents(pCsr);
memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
}
@@ -1216,64 +1156,27 @@
assert( pCsr->pExpr==0 );
assert( pCsr->csrflags==0 );
assert( pCsr->pRank==0 );
assert( pCsr->zRank==0 );
assert( pCsr->zRankArgs==0 );
- assert( pTab->pSortCsr==0 || nVal==0 );
assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
- /* Decode the arguments passed through to this function. */
- for(i=0; i='0' && idxStr[iIdxStr]<='9' ){
- iCol = 0;
- do{
- iCol = iCol*10 + (idxStr[iIdxStr]-'0');
- iIdxStr++;
- }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
- }else{
- iCol = pConfig->nCol;
- }
-
- if( zText[0]=='*' ){
- /* The user has issued a query of the form "MATCH '*...'". This
- ** indicates that the MATCH expression is not a full text query,
- ** but a request for an internal parameter. */
- rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
- goto filter_out;
- }else{
- char **pzErr = &pTab->p.base.zErrMsg;
- rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr);
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
- pExpr = 0;
- }
- if( rc!=SQLITE_OK ) goto filter_out;
- }
-
- break;
- }
- case '=':
- pRowidEq = apVal[i];
- break;
- case '<':
- pRowidLe = apVal[i];
- break;
- default: assert( idxStr[iIdxStr-1]=='>' );
- pRowidGe = apVal[i];
- break;
- }
- }
+ /* Decode the arguments passed through to this function.
+ **
+ ** Note: The following set of if(...) statements must be in the same
+ ** order as the corresponding entries in the struct at the top of
+ ** fts5BestIndexMethod(). */
+ if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++];
+ if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++];
+ if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
+ if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
+ if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
+ iCol = (idxNum>>16);
+ assert( iCol>=0 && iCol<=pConfig->nCol );
+ assert( iVal==nVal );
bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
/* Set the cursor upper and lower rowid limits. Only some strategies
** actually use them. This is ok, as the xBestIndex() method leaves the
@@ -1296,11 +1199,11 @@
** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will
** return results to the user for this query. The current cursor
** (pCursor) is used to execute the query issued by function
** fts5CursorFirstSorted() above. */
assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
- assert( nVal==0 && bOrderByRank==0 && bDesc==0 );
+ assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
assert( pCsr->iLastRowid==LARGEST_INT64 );
assert( pCsr->iFirstRowid==SMALLEST_INT64 );
if( pTab->pSortCsr->bDesc ){
pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid;
pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid;
@@ -1309,19 +1212,33 @@
pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid;
}
pCsr->ePlan = FTS5_PLAN_SOURCE;
pCsr->pExpr = pTab->pSortCsr->pExpr;
rc = fts5CursorFirst(pTab, pCsr, bDesc);
- }else if( pCsr->pExpr ){
+ }else if( pMatch ){
+ const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
+ if( zExpr==0 ) zExpr = "";
+
rc = fts5CursorParseRank(pConfig, pCsr, pRank);
if( rc==SQLITE_OK ){
- if( bOrderByRank ){
- pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
- rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
+ if( zExpr[0]=='*' ){
+ /* The user has issued a query of the form "MATCH '*...'". This
+ ** indicates that the MATCH expression is not a full text query,
+ ** but a request for an internal parameter. */
+ rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
}else{
- pCsr->ePlan = FTS5_PLAN_MATCH;
- rc = fts5CursorFirst(pTab, pCsr, bDesc);
+ char **pzErr = &pTab->p.base.zErrMsg;
+ rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
+ if( rc==SQLITE_OK ){
+ if( bOrderByRank ){
+ pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
+ rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
+ }else{
+ pCsr->ePlan = FTS5_PLAN_MATCH;
+ rc = fts5CursorFirst(pTab, pCsr, bDesc);
+ }
+ }
}
}
}else if( pConfig->zContent==0 ){
*pConfig->pzErrmsg = sqlite3_mprintf(
"%s: table does not support scanning", pConfig->zName
@@ -1334,21 +1251,19 @@
rc = sqlite3Fts5StorageStmt(
pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
);
if( rc==SQLITE_OK ){
if( pCsr->ePlan==FTS5_PLAN_ROWID ){
- sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
+ sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
}else{
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
}
rc = fts5NextMethod(pCursor);
}
}
- filter_out:
- sqlite3Fts5ExprFree(pExpr);
pConfig->pzErrmsg = pzErrmsg;
return rc;
}
/*
@@ -1425,28 +1340,21 @@
assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 );
assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
}
if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
assert( pCsr->pExpr );
sqlite3_reset(pCsr->pStmt);
sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr));
- pTab->pConfig->bLock++;
rc = sqlite3_step(pCsr->pStmt);
- pTab->pConfig->bLock--;
if( rc==SQLITE_ROW ){
rc = SQLITE_OK;
CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT);
}else{
rc = sqlite3_reset(pCsr->pStmt);
if( rc==SQLITE_OK ){
rc = FTS5_CORRUPT;
- }else if( pTab->pConfig->pzErrmsg ){
- *pTab->pConfig->pzErrmsg = sqlite3_mprintf(
- "%s", sqlite3_errmsg(pTab->pConfig->db)
- );
}
}
}
return rc;
}
@@ -2322,11 +2230,11 @@
assert( argc>=1 );
pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
iCsrId = sqlite3_value_int64(argv[0]);
pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
- if( pCsr==0 || pCsr->ePlan==0 ){
+ if( pCsr==0 ){
char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
}else{
fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
@@ -2458,16 +2366,14 @@
if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
}
}
}else if( !fts5IsContentless(pTab) ){
- pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
rc = fts5SeekCursor(pCsr, 1);
if( rc==SQLITE_OK ){
sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
}
- pConfig->pzErrmsg = 0;
}
return rc;
}
Index: ext/fts5/fts5_storage.c
==================================================================
--- ext/fts5/fts5_storage.c
+++ ext/fts5/fts5_storage.c
@@ -136,13 +136,11 @@
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
int f = SQLITE_PREPARE_PERSISTENT;
if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
- p->pConfig->bLock++;
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
- p->pConfig->bLock--;
sqlite3_free(zSql);
if( rc!=SQLITE_OK && pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
}
}
@@ -558,12 +556,10 @@
*/
int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
Fts5Config *pConfig = p->pConfig;
int rc;
- p->bTotalsValid = 0;
-
/* Delete the contents of the %_data and %_docsize tables. */
rc = fts5ExecPrintf(pConfig->db, 0,
"DELETE FROM %Q.'%q_data';"
"DELETE FROM %Q.'%q_idx';",
pConfig->zDb, pConfig->zName,
@@ -611,15 +607,14 @@
sqlite3Fts5BufferZero(&buf);
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){
ctx.szCol = 0;
if( pConfig->abUnindexed[ctx.iCol]==0 ){
- const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1);
- int nText = sqlite3_column_bytes(pScan, ctx.iCol+1);
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
- zText, nText,
+ (const char*)sqlite3_column_text(pScan, ctx.iCol+1),
+ sqlite3_column_bytes(pScan, ctx.iCol+1),
(void*)&ctx,
fts5StorageInsertCallback
);
}
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
@@ -737,15 +732,14 @@
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
}
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){
ctx.szCol = 0;
if( pConfig->abUnindexed[ctx.iCol]==0 ){
- const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]);
- int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]);
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
- zText, nText,
+ (const char*)sqlite3_value_text(apVal[ctx.iCol+2]),
+ sqlite3_value_bytes(apVal[ctx.iCol+2]),
(void*)&ctx,
fts5StorageInsertCallback
);
}
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
@@ -910,15 +904,14 @@
ctx.szCol = 0;
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
}
if( rc==SQLITE_OK ){
- const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
- int nText = sqlite3_column_bytes(pScan, i+1);
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
- zText, nText,
+ (const char*)sqlite3_column_text(pScan, i+1),
+ sqlite3_column_bytes(pScan, i+1),
(void*)&ctx,
fts5StorageIntegrityCallback
);
}
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
Index: ext/fts5/fts5_vocab.c
==================================================================
--- ext/fts5/fts5_vocab.c
+++ ext/fts5/fts5_vocab.c
@@ -571,14 +571,12 @@
}
}
}
if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
- for(/* noop */; pCsr->iColaDoc[pCsr->iCol]==0; pCsr->iCol++);
- if( pCsr->iCol==nCol ){
- rc = FTS5_CORRUPT;
- }
+ while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
+ assert( pCsr->iColpFts5->pConfig->nCol );
}
return rc;
}
/*
Index: ext/fts5/test/fts5content.test
==================================================================
--- ext/fts5/test/fts5content.test
+++ ext/fts5/test/fts5content.test
@@ -251,47 +251,7 @@
do_execsql_test 6.2 {
DROP TABLE xx;
SELECT name FROM sqlite_master;
} {}
-#---------------------------------------------------------------------------
-# Check that an fts5 table cannot be its own content table.
-#
-reset_db
-do_execsql_test 7.1.1 {
- CREATE VIRTUAL TABLE t1 USING fts5(a, c=t1 );
- INSERT INTO t1( a ) VALUES('abc');
-}
-do_catchsql_test 7.1.2 {
- SELECT * FROM t1;
-} {1 {recursively defined fts5 content table}}
-do_catchsql_test 7.1.3 {
- SELECT * FROM t1('abc');
-} {1 {recursively defined fts5 content table}}
-do_catchsql_test 7.1.4 {
- SELECT count(*) FROM t1;
-} {1 {recursively defined fts5 content table}}
-do_catchsql_test 7.1.5 {
- SELECT * FROM t1('abc') ORDER BY rank;
-} {1 {recursively defined fts5 content table}}
-
-reset_db
-do_execsql_test 7.2.1 {
- CREATE VIRTUAL TABLE t1 USING fts5(a, c=t2 );
- CREATE VIRTUAL TABLE t2 USING fts5(a, c=t1 );
- INSERT INTO t1( a ) VALUES('abc');
-}
-do_catchsql_test 7.2.2 {
- SELECT * FROM t1;
-} {1 {recursively defined fts5 content table}}
-do_catchsql_test 7.2.3 {
- SELECT * FROM t1('abc');
-} {1 {recursively defined fts5 content table}}
-do_catchsql_test 7.2.4 {
- SELECT count(*) FROM t1;
-} {1 {recursively defined fts5 content table}}
-do_catchsql_test 7.2.5 {
- SELECT * FROM t1('abc') ORDER BY rank;
-} {1 {recursively defined fts5 content table}}
finish_test
-
Index: ext/fts5/test/fts5corrupt3.test
==================================================================
--- ext/fts5/test/fts5corrupt3.test
+++ ext/fts5/test/fts5corrupt3.test
@@ -765,11 +765,11 @@
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
}]} {}
do_catchsql_test 13.1 {
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
-} {/*malformed database schema*/}
+} {1 {vtable constructor failed: t1}}
#-------------------------------------------------------------------------
reset_db
do_test 14.0 {
sqlite3 db {}
@@ -956,11 +956,11 @@
| end c16.db
}]} {}
do_catchsql_test 15.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
#---------------------------------------------------------------------------
#
reset_db
do_test 16.0 {
@@ -3901,23 +3901,23 @@
| 480: 00 00 39 00 00 00 00 00 00 00 00 00 00 00 00 00 ..9.............
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| end crash-fed6e90021ba5d.db
}]} {}
-do_catchsql_test 33.1 {
+do_execsql_test 33.1 {
CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row');
CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col');
CREATE VIRTUAL TABLE t4 USING fts5vocab('t1','instance');
-} {/*malformed database schema*/}
+}
do_catchsql_test 33.2 {
SELECT * FROM t2;
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
do_catchsql_test 33.3 {
SELECT * FROM t2, t3, t4 WHERE t2.term=t3.term AND t3.term=t4.term;
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 34.0 {
sqlite3 db {}
@@ -4482,11 +4482,11 @@
}]} {}
do_catchsql_test 36.1 {
INSERT INTO t1(b) VALUES(
x'78de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bfef346e6a');
-} {0 {}}
+} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 37.0 {
sqlite3 db {}
@@ -4635,21 +4635,21 @@
| end null-memcmp-param-1..db
}]} {}
do_catchsql_test 37.1 {
SELECT * FROM t3;
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
-do_execsql_test 37a.0 {
+do_execsql_test 37.0 {
CREATE VIRTUAL TABLE t1 USING fts5(b, c);
INSERT INTO t1 VALUES('a', 'b');
SELECT quote(block) FROM t1_data WHERE rowid=10;
} {X'000000000101010001010101'}
-do_execsql_test 37a.1 {
+do_execsql_test 37.1 {
UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10;
SELECT rowid FROM t1('a');
} {1}
#-------------------------------------------------------------------------
@@ -4666,10 +4666,11 @@
} {a b a b}
do_execsql_test 38.2 {
UPDATE t1_data SET block = X'000202' WHERE rowid=1;
}
+breakpoint
do_catchsql_test 38.3 {
SELECT * FROM t1('a b') ORDER BY rank;
} {1 {database disk image is malformed}}
db close
@@ -4892,11 +4893,11 @@
| end crash-fd2a1313e5b5e9.db
}]} {}
do_catchsql_test 38.1 {
UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*';
-} {/*malformed database schema*/}
+} {0 {}}
#-------------------------------------------------------------------------
reset_db
do_test 39.0 {
sqlite3 db {}
@@ -5324,20 +5325,20 @@
| 0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00 ................
| 4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09 ................
| end crash2.txt.db
}]} {}
-do_catchsql_test 40.1 {
+do_execsql_test 40.1 {
BEGIN;
INSERT INTO t1(b) VALUES(X'819192e578de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bf');
INSERT INTO t1(b) VALUES(X'c8ae0d0e7c3175946e62ba2b449511d4eb504079984a20f77969f62206c9f3d7ea25358ab705e6978627290b6d48db9032f815a06a79a4f4b809841a0942eed12954ed166f666111812a508abc3bec87958846edaec0a6fe14564bc0a4b78f1c35ebcacca6bae29cc37ae9b59d8a2d7593af1e47dda0ece2268a98d20febafad037964f139851f9a57f48b3706b01721769071991412044cd6006f1d72eb6eb4aa5ad77e378176db8c15575fbeee47165e38a7c6c5a557ac2dfe11813976eaf6741cf593a9e457053a3c34cddfbe605a6e25419f993de8374fafcd3636509d8416a51dc7bcc14cfca322ae343078f47e23522431c17d0da0c033');
INSERT INTO t1(b) VALUES(X'dc29a94e873a45a4243fce9b912aaefbadf1d0423e0345793874b356eeb500b92fb05284c1601fe9bad3143f72162f10242cec27c44ebf764c8fc9fb0824e32c4161472a4f914f579e0e8274f08ca1a02e59b9d8eec1f31061f9ccb9ed97a6f06534e991f7992c761489e6a7724f6e9c2b581e77487ded3a986d53c4419bbd3e9747cee300e670dd7294874c77e2ed48da68eaa6c3ec954a09ac410493d98e34d6686e54fbbe80696705f10e040c66093efb40746b33600685c94c664c7942835a9e954866121d5dcfb2cb12e92521ea3df175ee17072502dad9b9c1565f801b2179799011eb7418bfa00323e3157589e648ff7378be233c79b7');
-} {/*malformed database schema*/}
+}
do_catchsql_test 40.2 {
INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3, true ),(4,44);
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 41.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a,b,c);
@@ -5787,11 +5788,11 @@
| end 89028ffd2c29b679e250.db
}]} {}
do_catchsql_test 43.1 {
INSERT INTO t1(t1) VALUES('optimize');
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 44.1 {
CREATE VIRTUAL TABLE t1 USING fts5(a,b unindexed,c,tokenize="porter ascii");
@@ -5810,16 +5811,16 @@
INSERT INTO t1_docsize VALUES(2,X'030003');
INSERT INTO t1_docsize VALUES(3,X'030003');
} {}
do_catchsql_test 44.2 {
- INSERT INTO t1(t1) VALUES('integrity-check');
+INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
-do_catchsql_test 44.3 {
+do_catchsql_test 44.2 {
SELECT snippet(t1, -1, '.', '..', '', 2 ) FROM t1('g h') ORDER BY rank;
-} {0 {{.g.. .h..} {.g.. h} {.g.. .h..}}}
+} {1 {database disk image is malformed}}
#--------------------------------------------------------------------------
reset_db
do_test 45.0 {
sqlite3 db {}
@@ -6045,11 +6046,11 @@
INSERT INTO t1(t1, rank) VALUES('merge', 5);
INSERT INTO t1(t1, rank) VALUES('merge', 5);
INSERT INTO t1(t1, rank) VALUES('merge', 5);
INSERT INTO t1(t1, rank) VALUES('merge', 5);
INSERT INTO t1(t1, rank) VALUES('merge', 5);
-} {/*malformed database schema*/}
+} {0 {}}
#--------------------------------------------------------------------------
reset_db
do_test 46.0 {
sqlite3 db {}
@@ -6263,11 +6264,11 @@
| end crash-1ee8bd451dd1ad.db
}]} {}
do_catchsql_test 46.1 {
SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*');
-} {/*malformed database schema*/}
+} {0 {{}}}
#--------------------------------------------------------------------------
reset_db
do_test 47.0 {
sqlite3 db {}
@@ -6415,20 +6416,14 @@
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| end 4b6fc659283f2735616c.db
}]} {}
do_catchsql_test 47.1 {
- INSERT INTO t1(t1) VALUES('integrity-check');
-} {/*malformed database schema*/}
-
-do_catchsql_test 47.2 {
- SELECT count(*) FROM (
- SELECT snippet(t1, -1, '.', '..', '[', 50),
- highlight(t1, 2, '[', ']') FROM t1('g h')
- WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank
- )
-} {/*malformed database schema*/}
+ SELECT snippet(t1, -1, '.', '..', '[', 50),
+ highlight(t1, 2, '[', ']') FROM t1('g h')
+ WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank;
+} {1 {database disk image is malformed}}
#--------------------------------------------------------------------------
reset_db
do_test 48.0 {
sqlite3 db {}
@@ -6906,11 +6901,11 @@
SELECT term FROM t4 WHERE term LIKE '»as';
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
-do_execsql_test 51.0 {
+do_execsql_test 51.1 {
BEGIN TRANSACTION;
PRAGMA writable_schema=ON;
CREATE VIRTUAL TABLE t1 USING fts5(a,b,c);
CREATE TABLE IF NOT EXISTS 't1_data'(id INTEGER PRIMARY KEY, block BLOB);
REPLACE INTO t1_data VALUES(1,X'2eb1182424');
@@ -6974,11 +6969,11 @@
COMMIT;
} {}
do_catchsql_test 51.1 {
SELECT max(rowid)==0 FROM t1('e*');
-} {1 {database disk image is malformed}}
+} {0 0}
#--------------------------------------------------------------------------
reset_db
do_test 52.0 {
sqlite3 db {}
@@ -7128,11 +7123,11 @@
| end crash-2b92f77ddfe191.db
}]} {}
do_catchsql_test 52.1 {
SELECT fts5_decode(id, block) FROM t1_data;
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 53.0 {
sqlite3 db {}
@@ -7344,11 +7339,11 @@
}]} {}
do_catchsql_test 53.1 {
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10)
INSERT INTO t1(a) SELECT randomblob(3000) FROM c;
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 54.0 {
sqlite3 db {}
@@ -7560,11 +7555,11 @@
| end crash-03a1855566d9ae.db
}]} {}
do_catchsql_test 54.1 {
SELECT rowid==-1 FROM t1('t*');
-} {/*malformed database schema*/}
+} {0 {0 0 0}}
#-------------------------------------------------------------------------
reset_db
do_test 55.0 {
sqlite3 db {}
@@ -7775,14 +7770,14 @@
| 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb
| 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize
| end crash-b366b5ac0d3887.db
}]} {}
-do_catchsql_test 55.1 {
+do_execsql_test 55.1 {
SAVEPOINT one;
DELETE FROM t1 WHERE a MATCH 'ts';
-} {/*malformed database schema*/}
+}
do_execsql_test 55.2 {
ROLLBACK TO one;
}
@@ -8011,11 +8006,11 @@
# different results depending on whether or not the page-cache is in use.
if {$res=="1 {constraint failed}"} {
set res "1 {database disk image is malformed}"
}
set res
-} {/*malformed database schema*/}
+} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 57.0 {
sqlite3 db {}
@@ -8129,1986 +8124,11 @@
| end x.db
}]} {}
do_catchsql_test 57.1 {
INSERT INTO t1(t1) VALUES('optimize')
-} {/*malformed database schema*/}
-
-#-------------------------------------------------------------------------
-reset_db
-do_test 58.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 24576 pagesize 4096 filename crash-5a5acd0ab42d31.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
-| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
-| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
-| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
-| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
-| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
-| 3648: 74 31 5f 63 2a 6e 66 69 68 74 31 5f 63 6f 6e 66 t1_c*nfiht1_conf
-| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
-| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
-| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
-| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
-| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 73 73 !...tablet1_doss
-| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
-| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
-| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
-| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
-| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
-| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
-| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
-| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
-| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
-| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
-| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
-| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl
-| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
-| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
-| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
-| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
-| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
-| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
-| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
-| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
-| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 32 2c 32 2c 33 ,b,prefix=.2,2,3
-| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
-| page 2 offset 4096
-| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
-| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ae ...m.K.,........
-| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
-| 48: 0d 97 0d 76 0d 54 0d 30 fd 15 0c f3 0c d3 0c b5 ...v.T.0........
-| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
-| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a ad ...~.H..........
-| 96: 0a 8c 0a 6d 0a 4d 0a 2b 0a 0c 00 00 00 00 00 00 ...m.M.+........
-| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
-| 2384: 30 00 00 00 9c 01 03 35 00 03 01 01 12 02 01 12 0......5........
-| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
-| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
-| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
-| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
-| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
-| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the.....
-| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
-| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
-| 2528: 01 05 01 03 74 61 62 05 62 03 04 0a 19 8c 80 80 ....tab.b.......
-| 2544: 80 80 0c 03 00 38 00 00 00 14 03 39 a7 68 03 02 .....8.....9.h..
-| 2560: 04 10 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
-| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
-| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
-| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
-| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
-| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
-| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
-| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
-| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
-| 2704: 80 80 07 03 00 3a ff 00 00 15 02 31 6e 03 08 01 .....:.....1n...
-| 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
-| 2736: 80 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03 ......6......1f.
-| 2752: 02 01 f1 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i...........
-| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
-| 2784: 06 01 01 14 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
-| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
-| 2816: 06 30 74 61 62 6c cc 03 02 03 07 1c 8c 80 80 80 .0tabl..........
-| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
-| 2848: 72 03 06 01 01 05 01 02 6f 66 02 06 04 0d 13 8c r.......of......
-| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........
-| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n..............
-| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
-| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*.
-| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
-| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................
-| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
-| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
-| 2992: 15 88 80 80 80 80 10 03 00 3e 10 00 00 11 02 01 .........>......
-| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
-| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
-| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
-| 3056: 80 80 80 80 0e 03 05 0c 00 00 00 16 01 01 02 04 ................
-| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
-| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2
-| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
-| 3120: 04 01 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
-| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
-| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
-| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
-| 3184: 04 05 07 1b 88 80 bf 80 80 0a 03 00 3c 00 00 00 ............<...
-| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
-| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
-| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
-| 3248: 01 01 05 03 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
-| 3264: 01 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
-| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
-| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
-| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
-| 3328: 16 06 30 74 68 65 72 65 02 12 02 00 02 31 31 02 ..0there.....11.
-| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
-| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 71 01 07 .......0the..q..
-| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
-| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
-| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
-| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
-| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
-| 3456: 08 f0 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
-| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
-| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
-| 3504: 02 02 07 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
-| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
-| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
-| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
-| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70 .....4each.....p
-| 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res.............
-| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
-| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
-| 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre....
-| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
-| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for..
-| 3680: 02 02 02 74 73 01 06 01 01 04 03 f8 1b 84 80 80 ...ts...........
-| 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th..
-| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
-| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
-| 3744: 01 06 01 01 05 02 01 65 00 02 04 04 09 19 84 80 .......e........
-| 3760: 80 80 80 0a 03 10 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
-| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
-| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
-| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
-| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
-| 3840: 01 00 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
-| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
-| 3872: 06 01 01 02 de 01 70 01 02 05 04 08 18 84 80 80 ......p.........
-| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
-| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
-| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
-| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
-| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab
-| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le..............
-| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
-| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
-| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
-| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
-| 4048: 00 00 00 15 05 30 65 61 63 68 00 f2 03 01 03 66 .....0each.....f
-| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
-| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
-| page 3 offset 8192
-| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
-| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f c1 0f a9 0f a0 ................
-| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
-| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&....
-| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d7 0e cd ................
-| 80: 0e c3 0e ba 0e b0 0e a8 0e 9f 0e 96 0e 8e 0e 85 ................
-| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
-| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
-| 3680: 09 04 01 12 34 03 33 74 68 1c 08 04 01 10 01 03 ....4.3th.......
-| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
-| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
-| 3728: 01 0e 01 03 32 12 08 04 01 0f f1 03 31 74 10 08 ....2.......1t..
-| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 30 fc .....1n.......0.
-| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
-| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
-| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 05 52 08 04 01 ...0n.......R...
-| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
-| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
-| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 b3 02 .......2t.......
-| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
-| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n..
-| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
-| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
-| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
-| 3936: 04 01 10 01 02 30 62 06 09 04 01 10 01 02 30 61 .....0b.......0a
-| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
-| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
-| 3984: 07 04 09 10 01 33 70 1c 07 f4 09 11 01 33 66 1a .....3p......3f.
-| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 e4 .....2th......2.
-| 4016: 16 07 04 09 10 01 32 69 14 07 04 09 10 01 32 66 ......2i......2f
-| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
-| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
-| 4064: 0a 07 04 09 10 01 30 74 08 00 00 00 00 00 00 00 ......0t........
-| page 4 offset 12288
-| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
-| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
-| page 5 offset 16384
-| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
-| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
-| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
-| page 6 offset 20480
-| 4080: 00 00 23 03 02 01 03 03 02 00 00 00 00 00 00 00 ..#.............
-| end crash-5a5acd0ab42d31.db
-}]} {}
-
-do_catchsql_test 58.1 {
- SELECT * FROM t1('t*');
-} {/*malformed database schema*/}
-
-#-------------------------------------------------------------------------
-do_test 59.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 32768 pagesize 4096 filename crash-96b136358d01ec.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
-| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............
-| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
-| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
-| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
-| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
-| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
-| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
-| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
-| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
-| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
-| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
-| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
-| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
-| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
-| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
-| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
-| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
-| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
-| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
-| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
-| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i....
-| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
-| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
-| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
-| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
-| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
-| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
-| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
-| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
-| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
-| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
-| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
-| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
-| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
-| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
-| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
-| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
-| page 3 offset 8192
-| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................
-| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
-| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
-| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160
-| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3.
-| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5.....
-| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..=
-| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
-| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N.....
-| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
-| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
-| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat...........
-| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e
-| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
-| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
-| 3472: 01 02 02 01 02 02 01 02 01 f1 02 02 01 02 02 01 ................
-| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
-| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
-| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
-| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%.......
-| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
-| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........
-| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
-| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
-| 3616: 00 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
-| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
-| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
-| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase...........
-| 3680: 06 01 02 02 13 06 01 02 02 03 06 01 02 02 03 06 ................
-| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit.........
-| 3744: 01 0a 22 74 72 65 65 19 02 03 01 02 03 01 02 03 ...tree.........
-| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............
-| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
-| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
-| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
-| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
-| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................
-| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
-| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G..........
-| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
-| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
-| page 4 offset 12288
-| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
-| page 5 offset 16384
-| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
-| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
-| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
-| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE..
-| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
-| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 45 ed 0XRTRIM.!..3..E.
-| 3168: 49 54 20 4c 4f 41 44 21 45 58 54 45 4e 53 49 4f IT LOAD!EXTENSIO
-| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
-| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 5a 29 MIT LOAD EXTENZ)
-| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
-| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS
-| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3..
-| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000
-| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3.
-| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
-| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2
-| 3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500
-| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
-| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
-| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE.
-| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR
-| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
-| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI
-| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
-| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
-| 3504: 4d 53 59 76 35 58 52 54 52 49 4d 18 15 05 10 25 MSYv5XRTRIM....%
-| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB
-| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE.
-| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
-| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
-| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
-| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 5f 81 42 4c NARY....)..E_.BL
-| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE
-| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
-| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
-| 3680: 0f 1a 45 4e 41 42 4c 45 20 56 54 43 35 58 42 49 ..ENABLE VTC5XBI
-| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
-| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE...
-| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
-| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
-| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY..
-| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
-| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e WNOCASE....#..EN
-| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM.
-| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
-| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
-| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
-| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR
-| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
-| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
-| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM
-| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
-| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
-| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?.
-| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
-| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C
-| 4064: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 00 E.`YLER=gcc-5.4.
-| page 6 offset 20480
-| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
-| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
-| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . ..............
-| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
-| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
-| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
-| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
-| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
-| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
-| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
-| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
-| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
-| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 10 12 02 01 01 ................
-| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................
-| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
-| 4048: 07 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
-| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
-| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
-| page 7 offset 24576
-| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| page 8 offset 28672
-| 4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00 ......]..+int...
-| end crash-96b136358d01ec.db
-}]} {}
-
-do_catchsql_test 59.1 {
- SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*e'
-} {1 {database disk image is malformed}}
-
-#-------------------------------------------------------------------------
-do_test 60.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 32768 pagesize 4096 filename crash-c77b90b929dc92.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
-| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............
-| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
-| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
-| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
-| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
-| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
-| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
-| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
-| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
-| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
-| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
-| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
-| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
-| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
-| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
-| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
-| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
-| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
-| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
-| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
-| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i....
-| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
-| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
-| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
-| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
-| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
-| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
-| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
-| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
-| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
-| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
-| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
-| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
-| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
-| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
-| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
-| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
-| page 3 offset 8192
-| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................
-| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
-| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
-| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160
-| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3.
-| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5.....
-| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..=
-| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
-| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N.....
-| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
-| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
-| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat...........
-| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e
-| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
-| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
-| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
-| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
-| 3504: 02 01 02 02 02 08 76 b4 65 6e 73 69 6f 6e 1f 02 ......v.ension..
-| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
-| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%.......
-| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
-| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........
-| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
-| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
-| 3616: 00 03 6d 61 78 1c 02 0c 01 02 02 01 02 02 02 05 ..max...........
-| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
-| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
-| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase...........
-| 3680: 06 01 12 02 13 06 01 02 02 03 06 01 02 02 03 06 ................
-| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit.........
-| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree.........
-| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............
-| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
-| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
-| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
-| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
-| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................
-| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
-| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G..........
-| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
-| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
-| page 4 offset 12288
-| 0: 0a 00 00 00 01 0f 00 00 00 00 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
-| page 5 offset 16384
-| 0: 0d 00 00 00 24 0c 0a 00 0f 00 00 00 00 00 00 00 ....$...........
-| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
-| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
-| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
-| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE..
-| 3136: 05 00 25 0f 17 54 48 52 45 41 44 43 41 46 45 3d ..%..THREADCAFE=
-| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
-| 3168: 49 54 20 4b 4f 41 44 21 45 58 54 45 4e 53 49 4f IT KOAD!EXTENSIO
-| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
-| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
-| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
-| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS
-| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3..
-| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000
-| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3.
-| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
-| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2
-| 3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500
-| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
-| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
-| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE.
-| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR
-| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
-| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI
-| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
-| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
-| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 10 25 MSYS5XRTRIM....%
-| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB
-| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE.
-| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
-| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
-| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
-| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4f 81 42 4c NARY....)..EO.BL
-| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE
-| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
-| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
-| 3680: 0f 1a 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
-| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
-| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE...
-| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
-| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
-| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY..
-| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
-| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e WNOCASE....#..EN
-| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM.
-| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
-| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
-| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
-| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 8a 4e 41 52 .....DEBUGXB.NAR
-| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
-| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
-| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM
-| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
-| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
-| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?.
-| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
-| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C
-| 4064: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 2e E.`YLER=gcc-5.4.
-| 4080: 30 20 32 30 31 36 30 36 30 39 68 52 54 52 49 4d 0 20160609hRTRIM
-| page 6 offset 20480
-| 0: 0d 00 00 00 24 0e 00 00 00 00 00 00 00 00 00 00 ....$...........
-| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
-| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
-| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . ..............
-| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
-| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
-| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
-| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
-| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
-| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
-| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
-| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
-| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
-| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................
-| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................
-| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
-| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
-| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
-| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
-| page 7 offset 24576
-| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| page 8 offset 28672
-| 4048: 00 00 00 00 00 00 5d 03 00 00 00 00 00 00 00 00 ......].........
-| end crash-c77b90b929dc92.db
-}]} {}
-
-
-do_catchsql_test 60.2 {
- SELECT (matchinfo(t1,591)) FROM t1 WHERE t1 MATCH 'e*e'
-} {1 {database disk image is malformed}}
-
-#-------------------------------------------------------------------------
-do_test 61.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 28672 pagesize 4096 filename crash-e5fa281edabddf.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 0f c7 00 06 0d b6 00 0f 8d 0f 36 ...............6
-| 112: 0e cb 0e 6b 0e 0e 0d b6 00 00 00 00 00 00 00 00 ...k............
-| 3504: 00 00 00 00 00 00 56 07 06 17 1f 1f 01 7d 74 61 ......V.......ta
-| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
-| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
-| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
-| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
-| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
-| 3600: 07 17 21 21 01 81 01 74 51 62 6c 65 74 31 5f 64 ..!!...tQblet1_d
-| 3616: 6f 63 73 69 7a 65 74 31 5f 63 6f 63 73 69 7a 65 ocsizet1_cocsize
-| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
-| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
-| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
-| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
-| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
-| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
-| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
-| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
-| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
-| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
-| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
-| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
-| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
-| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
-| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
-| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
-| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
-| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
-| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
-| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
-| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
-| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
-| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 ea 74 31 43 52 ...._tablet.t1CR
-| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
-| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
-| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
-| page 3 offset 8192
-| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................
-| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
-| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
-| 3248: 1f 02 13 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160
-| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4.
-| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5.....
-| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000...
-| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
-| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
-| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
-| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat...........
-| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e
-| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
-| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
-| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
-| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
-| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
-| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
-| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5.......
-| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
-| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........
-| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
-| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
-| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
-| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
-| 3648: 73 79 73 35 16 02 03 01 02 03 11 02 03 01 06 6e sys5...........n
-| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase...........
-| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
-| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit.........
-| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree.........
-| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............
-| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3792: 02 02 03 06 01 02 02 03 06 01 02 01 13 05 01 02 ................
-| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
-| 3840: 02 02 01 01 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
-| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
-| 3872: 02 0e 16 01 01 02 01 06 01 01 02 01 06 01 02 02 ................
-| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
-| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 07 01 ................
-| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
-| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G..........
-| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
-| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
-| page 4 offset 12288
-| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
-| page 5 offset 16384
-| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
-| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
-| 3104: 4e 41 52 59 18 e2 05 00 25 0f 19 54 48 52 45 41 NARY....%..THREA
-| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE..
-| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
-| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
-| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO
-| 3184: 4e 58 42 49 4e 40 52 59 1f 20 05 00 33 0f 19 4f NXBIN@RY. ..3..O
-| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
-| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
-| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS
-| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3..
-| 3264: 4d 41 58 20 4e 45 4d 4f 52 59 3d 35 30 30 30 30 MAX NEMORY=50000
-| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3.
-| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 45 30 30 30 .MAX MEMORY=E000
-| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3
-| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500
-| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
-| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
-| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE.
-| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 20 54 52 ...%..ENABLE TR
-| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
-| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI
-| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
-| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
-| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....%
-| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB
-| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE.
-| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
-| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
-| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
-| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45 E GEOPOLYXNOCASE
-| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
-| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
-| 3680: 0f 19 45 4e 41 42 4c 45 20 e5 54 53 35 58 42 49 ..ENABLE .TS5XBI
-| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4d NARY....#..ENABM
-| 3712: 45 b5 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E.FTS5XNOCASE...
-| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
-| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
-| 3760: 4c 45 20 46 54 53 34 58 42 b7 4e 41 52 59 17 0b LE FTS4XB.NARY..
-| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
-| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN
-| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM.
-| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
-| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
-| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
-| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR
-| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
-| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
-| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM
-| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
-| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
-| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g
-| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
-| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 53 9XNOCASE&...C..S
-| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4.
-| 4080: 30 20 32 2f 31 00 00 00 00 00 00 00 00 00 00 00 0 2/1...........
-| page 6 offset 20480
-| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
-| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
-| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . ..............
-| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
-| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
-| 3888: 06 1a 03 00 12 02 01 01 06 19 03 10 12 02 01 01 ................
-| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
-| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
-| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
-| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
-| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
-| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
-| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................
-| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................
-| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
-| 4048: 06 06 03 00 12 01 01 01 06 05 03 01 12 01 01 01 ................
-| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
-| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
-| page 7 offset 24576
-| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| end crash-e5fa281edabddf.db
-}]} {}
-
-do_catchsql_test 61.1 {
- CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' );
-} {/*malformed database schema*/}
-
-do_catchsql_test 61.2 {
- SELECT * FROM t3 ORDER BY rowid;
-} {/*malformed database schema*/}
-
-breakpoint
-#-------------------------------------------------------------------------
-do_test 62.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 28672 pagesize 4096 filename crash-44942694542e1e.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
-| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............
-| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
-| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
-| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
-| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 79 67 74 31 5f 63 blet1_confygt1_c
-| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
-| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
-| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
-| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
-| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
-| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
-| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
-| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
-| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
-| 3680: 59 2c 20 73 7a 20 52 4c 4f 42 29 5e 05 07 17 21 Y, sz RLOB)^...!
-| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
-| 3712: 65 6e 74 74 35 ff 63 6f 6e 74 65 6e 74 05 43 52 entt5.content.CR
-| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
-| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
-| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
-| 3776: 63 30 2c 20 63 31 2c 20 63 42 29 69 04 07 17 19 c0, c1, cB)i....
-| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
-| 3808: 31 5f 79 64 78 04 43 52 45 41 54 45 20 54 41 42 1_ydx.CREATE TAB
-| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
-| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
-| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
-| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
-| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
-| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 74 61 ablet1_datat1_ta
-| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
-| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
-| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
-| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
-| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
-| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
-| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
-| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
-| page 3 offset 8192
-| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................
-| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
-| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
-| 3248: 2f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 /..........20160
-| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4.
-| 3280: 02 05 01 02 c7 01 02 05 01 01 35 01 02 04 01 02 ..........5.....
-| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000...
-| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
-| 3328: 01 02 02 04 16 01 02 02 03 06 01 02 02 02 06 01 ................
-| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3360: 02 03 06 01 02 02 03 06 01 02 02 02 06 01 02 02 ................
-| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
-| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
-| 3408: 62 73 74 61 74 07 02 03 00 02 03 01 02 03 02 04 bstat...........
-| 3424: 65 62 74 67 04 02 02 01 02 02 01 02 02 01 06 65 ebtg...........e
-| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
-| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 01 f1 02 02 ................
-| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
-| 3488: 02 02 01 02 02 45 02 02 01 02 02 01 02 02 01 02 .....E..........
-| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
-| 3520: 04 01 02 09 c1 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
-| 3536: 01 02 03 01 02 03 04 00 35 0d 02 03 01 02 04 01 ........5.......
-| 3552: 02 03 01 0f d7 63 63 01 02 03 01 02 03 01 02 03 .....cc.........
-| 3568: 02 06 65 6f 70 6f 6b 79 10 02 03 01 02 03 01 02 ..eopoky........
-| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 14 02 03 01 02 ...json1........
-| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
-| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
-| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
-| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
-| 3664: 6f 63 61 73 65 02 06 01 02 12 03 06 01 02 02 03 ocase...........
-| 3680: 06 01 02 02 03 06 01 02 02 09 f6 01 02 02 03 06 ................
-| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 11 02 ................
-| 3728: 02 01 04 6f 7d 69 74 1f 02 02 01 02 02 01 02 02 ...o.it.........
-| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree.........
-| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............
-| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 11 02 ................
-| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3824: 00 fa 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
-| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 03 04 01 40 .......vtab....@
-| 3856: 04 01 02 04 11 01 78 01 06 01 01 02 01 06 01 01 ......x.........
-| 3872: 02 01 06 01 00 02 01 06 01 01 02 01 03 91 01 02 ................
-| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
-| 3968: 01 06 01 01 02 01 76 01 01 02 01 06 01 01 02 5c ......v.........
-| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 11 06 ................
-| 4000: 01 02 02 01 06 08 11 02 01 06 01 01 02 01 06 01 ................
-| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 05 01 01 ................
-| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
-| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 ca 0e 10 0f .D...G..........
-| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 14 24 0f D..@.......$Z.$.
-| 4080: 0a 03 00 24 ff ff ff ff 01 01 02 00 01 01 01 01 ...$............
-| page 4 offset 12288
-| 0: 0a 00 00 00 01 0f fb 00 00 00 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
-| page 5 offset 16384
-| 0: 0d 00 00 00 24 0c 09 00 00 00 00 00 00 00 00 00 ....$...........
-| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
-| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
-| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
-| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 47 17 22 DSAFE=0XNOCASG..
-| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
-| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
-| 3168: 49 54 20 4c 3f 41 44 20 45 58 54 45 4e 53 49 4f IT L?AD EXTENSIO
-| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
-| 3200: 4d 49 64 20 4c 4f 41 44 20 45 58 54 45 d9 53 49 MId LOAD EXTE.SI
-| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
-| 3232: 4f 4d 39 54 20 4c 4f 41 44 20 45 58 55 45 4e 53 OM9T LOAD EXUENS
-| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3..
-| 3264: 4c 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 LAX MEMORY=50000
-| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3.
-| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
-| 3312: 30 30 30 30 58 af 4f 43 41 53 45 1e 1c 05 00 33 0000X.OCASE....3
-| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500
-| 3344: 30 30 ab 30 30 58 62 54 52 49 4d 18 1b 05 00 25 00.00XbTRIM....%
-| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
-| 3376: 49 4e 41 52 59 18 1b 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE.
-| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR
-| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
-| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 63 35 58 42 49 NABLE MEMSYc5XBI
-| 3456: 4e 41 52 59 1a 17 04 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
-| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 3d 45 ....)..ENABLE =E
-| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....%
-| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB
-| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3552: 4c 46 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LF JSON1XNOCASE.
-| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
-| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
-| 3600: 4e 41 42 4c 45 20 46 45 46 50 4f 4c 59 57 42 49 NABLE FEFPOLYWBI
-| 3616: 4e 41 52 59 18 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 5f 43 41 53 45 E GEOPOLYXN_CASE
-| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 42 ....)..ENABLE GB
-| 3664: 2f 50 4f 4c 59 58 51 54 52 49 4d 17 0f 05 00 23 /POLYXQTRIM....#
-| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
-| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
-| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE...
-| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
-| 3744: 52 54 52 49 4d 17 1c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
-| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 16 0b LE FTS4XBINARY..
-| 3776: 05 00 22 0f e9 45 4e 41 42 4c 35 20 46 54 53 34 .....ENABL5 FTS4
-| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 00 47 45 4e XNOCASE....#.GEN
-| 3808: 41 42 4c 45 20 46 54 53 34 57 52 54 52 49 4d 1e ABLE FTS4WRTRIM.
-| 3824: 60 05 00 31 0f 19 45 4e 41 42 4c 55 20 43 42 53 `..1..ENABLU CBS
-| 3840: 54 41 54 20 56 54 42 42 58 42 49 4e 41 52 59 1e TAT VTBBXBINARY.
-| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3872: 54 40 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d T@T VTABXNOCASE.
-| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 55 20 44 42 53 ...1..ENABLU DBS
-| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 12 06 TAT VTABXRTRIM..
-| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR
-| 3936: 59 21 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y!......DEBUGXNO
-| 3952: 43 41 53 45 10 04 05 00 17 0f 18 44 45 42 55 47 CASE.......DEBUG
-| 3968: 58 42 54 52 49 4d 27 11 05 00 43 0f 19 43 4f 4d XBTRIM'...C..COM
-| 3984: 50 49 48 f5 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PIH.R=gcc-5.4.0
-| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
-| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g
-| 4032: 63 63 2d 35 2e 34 2e 30 22 32 30 31 36 30 36 30 cc-5.4.0.2016060
-| 4048: 39 c2 3e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9.>OCASE&...C..C
-| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4.
-| 4080: 30 30 32 30 31 26 30 36 30 39 58 52 54 52 49 4d 00201&0609XRTRIM
-| page 6 offset 20480
-| 0: 0d 00 00 00 24 0e e0 00 00 00 00 00 00 00 00 00 ....$...........
-| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
-| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
-| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . ..............
-| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
-| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
-| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
-| 3904: 06 18 03 00 12 02 01 00 f6 17 03 00 19 e2 f9 01 ................
-| 3920: 06 16 03 00 12 02 05 01 06 15 03 00 12 02 01 01 ................
-| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
-| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
-| 3968: 06 10 03 10 12 02 01 01 06 0f 03 00 12 02 01 01 ................
-| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 00 f1 ................
-| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................
-| 4016: 06 0a 03 00 12 02 01 01 05 09 03 00 12 03 01 01 ................
-| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
-| 4048: 06 06 03 00 12 01 01 01 06 05 02 ff 84 01 01 01 ................
-| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
-| 4080: 07 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
-| page 7 offset 24576
-| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| end crash-44942694542e1e.db
-}]} {}
-
-do_catchsql_test 62.1 {
- WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72)
- INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
-} {/*malformed database schema*/}
-
-#---------------------------------------------------------------------------
-do_test 63.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 24576 pagesize 4096 filename crash-8230e6c3b368f5.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
-| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
-| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
-| 3600: 06 06 17 11 11 01 31 74 61 62 7c 65 62 63 62 62 ......1tab|ebcbb
-| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
-| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
-| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
-| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
-| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
-| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
-| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
-| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
-| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
-| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 9d EATE TABLE 't1_.
-| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
-| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
-| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
-| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
-| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
-| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
-| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
-| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
-| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
-| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl
-| 3936: 65 64 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 ed1_datat1_data.
-| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
-| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
-| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
-| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 10 11 lock BLOB)T.....
-| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
-| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
-| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
-| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
-| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
-| page 2 offset 4096
-| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
-| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
-| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
-| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
-| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
-| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a ad ...~.H..........
-| 96: 0a 8c 0a 6d 0a 4d 0a 2b 0a 0c 09 ec 09 ca 09 a8 ...m.M.+........
-| 112: 09 86 09 63 0f f1 00 00 00 00 00 00 00 00 00 00 ...c............
-| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
-| 2384: 30 00 00 00 01 01 03 35 00 03 01 01 12 02 01 12 0......5........
-| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
-| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
-| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
-| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
-| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
-| 2480: 00 3c 00 00 00 16 04 33 74 68 65 13 06 01 01 04 .<.....3the.....
-| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
-| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
-| 2528: 01 05 01 03 75 61 62 03 02 03 04 0a 19 8c 80 80 ....uab.........
-| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 ec 68 03 02 .....8.....2.h..
-| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
-| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
-| 2592: 03 02 01 68 03 06 01 01 04 04 17 1b 8c 80 80 80 ...h............
-| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
-| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
-| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
-| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
-| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
-| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
-| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
-| 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
-| 2736: 80 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03 ......6......1f.
-| 2752: 02 02 01 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i...........
-| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
-| 2784: 06 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
-| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
-| 2816: 06 30 74 61 62 6c 65 03 02 03 07 1c 8c 80 80 80 .0table.........
-| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
-| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
-| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........
-| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n..............
-| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
-| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*.
-| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
-| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................
-| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
-| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
-| 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0......
-| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
-| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
-| 3040: 02 06 01 01 05 01 03 74 68 64 02 08 05 0a 1b 88 .......thd......
-| 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........
-| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
-| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2
-| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
-| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
-| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
-| 3152: 01 43 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .C...........6..
-| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
-| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 00 00 ............<...
-| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
-| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
-| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
-| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
-| 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
-| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
-| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
-| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
-| 3328: 16 06 30 74 68 65 72 65 02 02 01 00 02 30 21 02 ..0there.....0!.
-| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
-| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the.....
-| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
-| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
-| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 51 .............<.Q
-| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
-| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
-| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
-| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
-| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
-| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
-| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
-| 3536: 00 16 05 34 74 51 62 6c 01 06 01 01 05 02 03 65 ...4tQbl.......e
-| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
-| 3568: 00 00 00 16 05 34 65 17 63 68 01 02 03 01 04 70 .....4e.ch.....p
-| 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res.............
-| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
-| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
-| 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre....
-| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
-| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 03 ....:.....3for..
-| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
-| 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th..
-| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
-| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
-| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
-| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
-| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
-| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
-| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
-| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
-| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
-| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
-| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
-| 3888: 80 80 06 03 00 36 00 00 00 12 02 31 65 01 02 02 .....6.....1e...
-| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
-| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
-| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
-| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab
-| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le..............
-| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
-| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
-| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
-| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
-| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 03 66 .....0each.....f
-| 4064: 6f 72 01 02 01 f4 09 06 01 03 00 12 03 0b 0f 00 or..............
-| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
-| page 3 offset 8192
-| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
-| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
-| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
-| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&....
-| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................
-| 80: 0e c3 0e ba 0e b0 0e a8 0e 9f 0e 00 00 00 00 00 ................
-| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
-| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
-| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
-| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
-| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
-| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 07 ....2.......1t..
-| 3744: f4 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
-| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
-| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
-| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
-| 3808: 10 01 02 34 73 22 07 04 01 0e 01 02 34 20 08 04 ...4s.......4 ..
-| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
-| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
-| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
-| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n..
-| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
-| 3904: 0e 0b 04 01 16 01 02 30 74 00 00 00 00 00 00 00 .......0t.......
-| page 4 offset 12288
-| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 02 03 00 10 ................
-| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
-| page 5 offset 16384
-| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
-| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
-| 4080: 67 73 7a 08 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
-| end crash-8230e6c3b368f5.db
-}]} {}
-
-do_catchsql_test 63.1 {
- SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
-} {/*malformed database schema*/}
-
-do_catchsql_test 63.2 {
- INSERT INTO t1(t1) VALUES('optimize');
-} {/*malformed database schema*/}
-
-do_catchsql_test 63.3 {
- SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
-} {/*malformed database schema*/}
-
-#---------------------------------------------------------------------------
-do_test 64.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 28672 pagesize 4096 filename crash-4470f0b94422f7.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 .....@ ........
-| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................
-| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j
-| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 01 00 00 .....=..........
-| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet
-| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con
-| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE
-| 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k
-| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v)
-| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WITHOUT ROWID^..
-| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d
-| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz
-| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE '
-| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id
-| 3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
-| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEY, sz BLOB)]..
-| 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c
-| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten
-| 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE '
-| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id
-| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
-| 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l...
-| 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id
-| 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE
-| 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'(
-| 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn
-| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s
-| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT
-| 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX.....
-| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data
-| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE
-| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data'
-| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
-| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B
-| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c LOB):......_tabl
-| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI
-| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt
-| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b)
-| page 2 offset 4096
-| 0: 0d 0f 44 00 05 0e 81 00 0f 1a 0e 81 0f af 0f 58 ..D............X
-| 16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0..........
-| 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$......
-| 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05 ...L.....0e.....
-| 3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07 ................
-| 3776: 05 07 05 07 05 01 01 04 03 03 08 03 03 08 03 03 ................
-| 3792: 07 f3 03 02 01 65 03 1e 03 05 05 04 05 05 01 00 .....e..........
-| 3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 06 05 04 ........6.......
-| 3824: 06 05 04 05 05 01 01 03 06 04 04 06 04 04 06 04 ................
-| 3840: 04 06 04 03 03 01 65 03 14 04 05 06 f5 05 01 01 ......e.........
-| 3856: 02 08 09 01 20 04 05 07 05 07 05 07 05 05 01 00 .... ...........
-| 3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 01 06 0a 0a 0a .......e........
-| 3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04 ..e.............
-| 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*.......
-| 3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04 ........P.......
-| 3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07 ..$...G.0e......
-| 3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1e 03 05 ...........e....
-| 3968: 05 04 05 05 01 01 03 06 04 04 06 04 03 03 01 65 ...............e
-| 3984: 02 14 04 05 07 05 05 01 01 02 08 0a 04 01 65 02 ..............e.
-| 4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31 ....e..........1
-| 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e
-| 4032: 01 10 02 05 05 01 01 04 03 03 02 01 65 01 12 03 ............e...
-| 4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 04 05 05 ..........e.....
-| 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL.
-| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
-| page 3 offset 8192
-| 0: 0a 00 00 00 03 0f ec 00 0f 00 00 00 00 00 00 00 ................
-| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c ................
-| 4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02 ................
-| page 4 offset 12288
-| 0: 0d 00 00 00 04 0e 1a 00 0f c7 0f 5b 0e ef 0e 1a ...........[....
-| 3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81 ...........R....
-| 3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee
-| 3632: 20 65 65 65 20 65 20 65 65 20 65 65 65 66 20 65 eee e ee eeef e
-| 3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e
-| 3664: 20 65 65 20 65 65 65 65 20 65 65 20 65 65 65 20 ee eeee ee eee
-| 3680: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 e ee eee e ee ee
-| 3696: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 ee ee eee e ee e
-| 3712: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65 ee e ee eeeeee e
-| 3728: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e e e e ee eee e
-| 3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 1f 65 e eeeee ee e e.e
-| 3760: 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 65 ee eee ee eeeee
-| 3776: 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 65 ee e e e ee eee
-| 3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 20 65 ee eeeee ee e e
-| 3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a e ee eee ee eej
-| 3824: 03 03 ff 75 71 65 20 65 65 1f 65 65 65 20 65 20 ...uqe ee.eee e
-| 3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65 ee eee e ee eeee
-| 3856: 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 ee eee e ee eee
-| 3872: 20 65 20 65 65 20 65 65 65 65 65 65 20 65 65 20 e ee eeeeee ee
-| 3888: 65 20 65 20 65 20 65 65 20 65 65 65 20 65 65 20 e e e ee eee ee
-| 3904: 65 65 65 65 65 20 65 65 20 65 20 65 20 65 20 65 eeeee ee e e e e
-| 3920: 65 20 65 65 65 20 65 65 20 65 65 6a 02 04 00 75 e eee ee eej...u
-| 3936: 40 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 @e ee eee e ee e
-| 3952: 65 65 20 65 20 65 65 20 65 65 65 65 20 65 65 20 ee e ee eeee ee
-| 3968: 65 65 65 20 65 20 65 65 20 65 65 65 20 65 20 65 eee e ee eee e e
-| 3984: 65 20 65 65 65 65 65 65 20 65 65 20 65 20 65 20 e eeeeee ee e e
-| 4000: 65 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 e ee eee ee eeee
-| 4016: 65 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 e ee e e e ee ee
-| 4032: 65 20 65 65 20 65 65 37 01 04 00 41 3f 65 20 65 e ee ee7...A?e e
-| 4048: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e
-| 4064: 20 65 65 20 65 65 65 65 65 65 20 65 65 20 65 20 ee eeeeee ee e
-| 4080: 65 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 e e ee eee ee ee
-| page 5 offset 16384
-| 0: 0d 00 00 00 04 0f e4 00 0f f9 0f f2 0f eb 0f e4 ................
-| 4064: 00 00 00 00 05 04 03 00 10 21 21 05 03 03 00 10 .........!!.....
-| 4080: 11 11 05 02 03 00 10 11 11 05 01 03 00 10 09 09 ................
-| page 6 offset 20480
-| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| end crash-4470f0b94422f7.db
-}]} {}
-
-do_catchsql_test 64.1 {
- SELECT * FROM ttt('e*');
-} {1 {database disk image is malformed}}
-
-#---------------------------------------------------------------------------
-do_test 65.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 28672 pagesize 4096 filename crash-3aef66940ace0c.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
-| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............
-| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
-| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
-| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
-| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
-| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
-| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
-| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
-| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
-| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
-| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
-| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
-| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
-| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
-| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
-| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
-| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
-| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
-| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
-| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
-| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i....
-| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
-| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
-| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
-| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
-| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
-| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
-| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
-| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
-| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
-| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
-| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
-| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
-| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
-| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
-| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
-| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
-| page 3 offset 8192
-| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................
-| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
-| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
-| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160
-| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3.
-| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5.....
-| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..=
-| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
-| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N.....
-| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
-| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
-| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat...........
-| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e
-| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
-| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
-| 3472: 01 02 02 01 02 01 f1 02 02 01 02 02 01 02 02 01 ................
-| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
-| 3504: 02 01 02 02 02 08 76 b4 65 6e 73 69 6f 6e 1f 02 ......v.ension..
-| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
-| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%.......
-| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
-| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........
-| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
-| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
-| 3616: 00 03 6d 61 78 1c 02 0c 01 02 02 01 02 02 02 05 ..max...........
-| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
-| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
-| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase...........
-| 3680: 06 01 12 02 13 06 01 02 02 03 06 01 02 02 03 06 ................
-| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit.........
-| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree.........
-| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............
-| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 8e 06 01 02 ................
-| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
-| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
-| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
-| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
-| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 3920: 01 01 02 01 06 01 01 01 01 06 01 01 02 01 06 01 ................
-| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................
-| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
-| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G..........
-| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
-| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
-| page 4 offset 12288
-| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
-| page 5 offset 16384
-| 0: 0d 00 00 00 24 0c 0a 00 00 00 00 00 00 00 00 00 ....$...........
-| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
-| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
-| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
-| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE..
-| 3136: 05 00 25 0f 17 54 48 52 45 41 44 43 41 46 45 3d ..%..THREADCAFE=
-| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
-| 3168: 49 54 20 4b 4f 41 44 21 45 58 54 45 4e 53 49 4f IT KOAD!EXTENSIO
-| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
-| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
-| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
-| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS
-| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3..
-| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000
-| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3.
-| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
-| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2
-| 3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500
-| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
-| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
-| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE.
-| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR
-| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
-| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI
-| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
-| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
-| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 10 25 MSYS5XRTRIM....%
-| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB
-| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE.
-| 3568: 13 05 00 25 0f 17 45 4d 41 42 4c 45 20 4a 53 4f ...%..EMABLE JSO
-| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
-| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
-| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4f 81 42 4c NARY....)..EO.BL
-| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE
-| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
-| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
-| 3680: 0f 1a 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
-| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
-| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE...
-| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
-| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
-| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY..
-| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
-| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e WNOCASE....#..EN
-| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM.
-| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
-| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
-| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
-| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 8a 4e 41 52 .....DEBUGXB.NAR
-| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
-| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
-| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM
-| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
-| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
-| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?.
-| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
-| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C
-| 4064: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 2d E.`YLER=gcc-5.4-
-| 4080: 30 20 32 30 31 36 30 36 30 39 00 00 00 00 00 00 0 20160609......
-| page 6 offset 20480
-| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
-| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
-| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . ..............
-| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
-| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
-| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
-| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
-| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
-| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
-| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
-| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
-| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
-| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................
-| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................
-| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
-| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
-| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
-| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
-| page 7 offset 24576
-| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| end crash-3aef66940ace0c.db
-}]} {}
-
-do_catchsql_test 65.1 {
- SELECT ( MATCH (t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ'
-} {1 {database disk image is malformed}}
-
-#-------------------------------------------------------------------------
-#
-reset_db
-do_test 66.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 28672 pagesize 4096 filename crash-37cecb4e784e9f.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07 .....@ ........
-| 96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d ...............m
-| 112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00 .....N..........
-| 3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
-| 3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
-| 3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
-| 3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
-| 3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
-| 3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
-| 3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
-| 3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05 WITHOUT ROWID[.
-| 3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
-| 3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
-| 3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
-| 3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
-| 3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
-| 3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21 Y, sz BLOB)U...!
-| 3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 !.wtablet1_conte
-| 3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45 ntt1_content.CRE
-| 3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f ATE TABLE 't1_co
-| 3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45 ntent'(id INTEGE
-| 3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63 R PRIMARY KEY, c
-| 3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 0)i.......-table
-| 3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 t1_idxt1_idx.CRE
-| 3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 ATE TABLE 't1_id
-| 3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 x'(segid, term,
-| 3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 pgno, PRIMARY KE
-| 3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 Y(segid, term))
-| 3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 WITHOUT ROWIDU..
-| 3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 ......tablet1_da
-| 3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 tat1_data.CREATE
-| 3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 TABLE 't1_data'
-| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
-| 4016: 41 52 49 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARI KEY, block B
-| 4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c LOB):......ctabl
-| 4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT
-| 4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI
-| 4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29 NG fts5(content)
-| page 2 offset 4096
-| 0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 01 ................
-| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80 .............$..
-| 4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61 ......N.....0aba
-| 4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64 ck.....ft.....nd
-| 4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f on..............
-| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 00 01 01 ...$............
-| page 3 offset 8192
-| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
-| page 4 offset 12288
-| 0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00 ................
-| 4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00 .....abandon....
-| 4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b .abaft.....aback
-| page 5 offset 16384
-| 0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00 ................
-| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03 ................
-| 4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01 ................
-| page 6 offset 20480
-| 0: 0a 00 00 01 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| page 7 offset 24576
-| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00 ................
-| 4048: 00 00 00 00 00 00 09 01 52 1b 72 65 62 75 69 6c ........R.rebuil
-| 4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63 d...+integrity-c
-| 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 heck....optimize
-| end crash-37cecb4e784e9f.db
-}]} {}
-
-do_catchsql_test 66.1 {
- INSERT INTO t1(t1) VALUES('integrity-check');
-} {1 {database disk image is malformed}}
-
-#-------------------------------------------------------------------------
-#
-reset_db
-do_test 67.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 24576 pagesize 4096 filename crash-43ed0ad79c0194.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j
-| 112: 0e fc 0e 9d 0e 3d 0d e2 01 00 00 00 00 00 00 00 .....=..........
-| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet
-| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con
-| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE
-| 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k
-| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v)
-| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WITHOUT ROWID^..
-| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d
-| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz
-| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE '
-| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id
-| 3712: 49 4e 54 45 47 45 52 20 51 52 49 4d 41 52 59 20 INTEGER QRIMARY
-| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEY, sz BLOB)]..
-| 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c
-| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten
-| 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE '
-| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id
-| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 f1 59 20 INTEGER PRIMA.Y
-| 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l...
-| 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id
-| 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE
-| 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'(
-| 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn
-| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s
-| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT
-| 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX.....
-| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data
-| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE
-| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data'
-| 4000: 28 69 64 20 49 4e 54 45 47 55 52 20 50 52 49 4d (id INTEGUR PRIM
-| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B
-| 4032: 4c 50 42 29 3a 02 06 17 13 13 08 5f 74 61 62 6c LPB):......_tabl
-| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI
-| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt
-| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b)
-| page 2 offset 4096
-| 0: 0d 0f 44 00 05 0e 71 00 0f e7 0e 81 0f af 0f 58 ..D...q........X
-| 16: 0e 98 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0..........
-| 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$......
-| 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 12 05 05 ...L.....0e.....
-| 3760: 07 05 01 01 04 03 03 08 04 03 01 2e 02 05 f7 07 ................
-| 3776: 01 e6 f5 07 05 01 01 04 03 03 01 22 03 18 03 03 ................
-| 3792: 08 03 03 02 01 65 03 1e 03 05 05 04 05 05 01 01 .....e..........
-| 3808: 03 06 03 f4 06 04 03 00 36 03 ff 05 04 05 05 04 ........6.......
-| 3824: 05 05 04 05 04 f1 01 03 06 04 04 06 04 04 06 04 ................
-| 3840: 04 07 04 03 03 01 65 03 14 04 05 07 05 05 01 01 ......e.........
-| 3856: 02 08 a5 01 20 04 05 01 94 f7 05 07 05 05 01 01 .... ...........
-| 3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 00 06 0a 0a 0a .......e........
-| 3888: 05 01 65 03 06 a7 01 0a 01 0a 01 01 0a 0a 0a 04 ..e.............
-| 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*.......
-| 3920: 00 02 01 01 01 02 11 01 50 88 80 80 80 80 01 04 ........P.......
-| 3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07 ..$...G.0e......
-| 3952: 05 e6 01 07 aa e3 08 03 03 02 01 65 02 1e 03 05 ...........e....
-| 3968: 05 05 04 f5 01 01 03 06 04 04 06 04 13 03 01 65 ...............e
-| 3984: 02 14 04 05 07 05 05 01 f7 f2 08 0a 04 01 65 02 ..............e.
-| 4000: 02 0a 05 01 65 02 06 00 f1 0a 04 12 14 0f 06 31 ....e..........1
-| 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e
-| 4032: 01 10 02 05 05 00 01 04 03 03 02 01 65 01 12 03 ............e...
-| 4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 04 05 04 ..........e.....
-| 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL.
-| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 02 ...$............
-| page 3 offset 8192
-| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| page 4 offset 12288
-| 3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81 ...........R....
-| 3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee
-| 3632: 20 65 65 65 28 15 20 65 65 20 65 65 65 65 20 65 eee(. ee eeee e
-| 3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e
-| 3664: 20 65 65 20 65 65 65 65 20 65 66 20 65 65 55 20 ee eeee ef eeU
-| 3680: 65 20 65 55 20 65 65 65 20 65 20 65 65 20 65 65 e eU eee e ee ee
-| 3696: 65 64 20 65 61 c0 65 65 65 20 65 20 65 65 20 65 ed ea.eee e ee e
-| 3712: 65 65 20 79 20 65 65 20 65 65 65 65 65 65 20 65 ee y ee eeeeee e
-| 3728: 65 1f 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e.e e e ee eee e
-| 3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 20 65 e eeeee ee e e e
-| 3760: 20 65 65 20 65 65 65 20 6b 85 20 65 65 65 66 65 ee eee k. eeefe
-| 3776: 20 65 65 10 65 20 65 20 65 20 65 65 20 65 65 65 ee.e e e ee eee
-| 3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 20 65 ee eeeee ee e e
-| 3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a e ee eee ee eej
-| 3824: 03 04 00 75 71 65 20 65 65 20 65 65 65 20 65 30 ...uqe ee eee e0
-| 3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65 ee eee e ee eeee
-| 3856: 20 65 65 20 65 65 65 20 65 1f 65 65 20 65 65 65 ee eee e.ee eee
-| 3872: 20 65 20 65 65 20 65 65 65 65 65 66 20 65 65 20 e ee eeeeef ee
-| 3888: 65 21 27 20 65 20 55 65 20 66 65 64 20 65 65 00 e!' e Ue fed ee.
-| page 5 offset 16384
-| 4064: 00 00 00 00 05 04 03 00 10 11 20 05 03 03 00 10 .......... .....
-| 4080: 11 11 05 02 03 00 00 11 11 05 01 03 00 10 09 09 ................
-| page 6 offset 20480
-| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 01 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| end crash-43ed0ad79c0194.db
-}]} {}
-
-do_catchsql_test 67.1 {
- SELECT snippet(ttt, null,null,
- EXISTS(SELECT 1 FROM ttt('e NuOT ee*e*ÏNuOY ee*') ) , '',
- (SELECT 1 FROM ttt('eu NuOT ee*e* NuOY ee*'))
- ), * FROM ttt('e')
-} {1 {database disk image is malformed}}
-
-#-------------------------------------------------------------------------
-#
-reset_db
-do_test 68.0 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-.open --hexdb
-| size 32768 pagesize 4096 filename crash-41234e232809e7.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........
-| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................
-| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
-| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............
-| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
-| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
-| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
-| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
-| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
-| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
-| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
-| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
-| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
-| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
-| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
-| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
-| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
-| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
-| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
-| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
-| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
-| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
-| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
-| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
-| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
-| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
-| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
-| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
-| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
-| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
-| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
-| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
-| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
-| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
-| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
-| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
-| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
-| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
-| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
-| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
-| page 3 offset 8192
-| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................
-| 16: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
-| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
-| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
-| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160
-| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 00 01 34 01 609...........4.
-| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5.....
-| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000...
-| 3312: 01 02 04 01 02 03 f1 06 62 69 6e 62 72 79 03 06 ........binbry..
-| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 01 03 16 01 ................
-| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3376: 03 04 71 02 02 03 06 11 02 02 01 08 63 6f 6d 70 ..q.........comp
-| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
-| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat...........
-| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e
-| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
-| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 03 02 ................
-| 3472: 00 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
-| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
-| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
-| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
-| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5.......
-| 3552: 02 03 01 03 66 63 63 01 02 03 01 02 03 01 02 03 ....fcc.........
-| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........
-| 3584: 03 01 05 6a 73 6f 5e 31 13 02 03 01 02 03 01 02 ...jso^1........
-| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
-| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
-| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
-| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
-| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase...........
-| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 13 06 ................
-| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit.........
-| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree.........
-| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 12 02 03 06 ..im............
-| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
-| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
-| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
-| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
-| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
-| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
-| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
-| 3888: 01 06 01 01 02 01 06 01 01 02 01 05 f1 01 02 01 ................
-| 3904: 06 01 01 02 01 06 01 5b 02 01 06 01 01 02 01 06 .......[........
-| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
-| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
-| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
-| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
-| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
-| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
-| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G..........
-| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
-| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
-| page 4 offset 12288
-| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0b 01 02 ................
-| page 5 offset 16384
-| 0: 0d 00 00 00 24 0c 0a 00 0f d8 0f af 0f 86 0f 74 ....$..........t
-| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./..........
-| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$......
-| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb .......h.O.5....
-| 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$..
-| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
-| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
-| 3104: 4f 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 OARY.#..%..THREA
-| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE..
-| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
-| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
-| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO
-| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
-| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
-| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
-| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS
-| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3..
-| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000
-| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3.
-| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
-| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3
-| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500
-| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
-| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
-| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3392: 4c 45 20 52 54 52 46 45 58 4e 4f 43 41 53 45 17 LE RTRFEXNOCASE.
-| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR
-| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
-| 3440: 49 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 IABLE MEMSYS5XBI
-| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
-| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
-| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....%
-| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB
-| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
-| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE.
-| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
-| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
-| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 57 42 49 NABLE GEOPOLYWBI
-| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
-| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 42 41 53 45 E GEOPOLYXNOBASE
-| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
-| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
-| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
-| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
-| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE...
-| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
-| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
-| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY..
-| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
-| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN
-| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM.
-| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
-| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
-| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
-| 3888: 07 05 00 31 0f 17 b7 4e 41 42 4c 45 20 44 42 53 ...1...NABLE DBS
-| 3904: 54 41 54 20 66 54 41 42 58 52 54 52 49 4d 11 06 TAT fTABXRTRIM..
-| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR
-| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
-| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
-| 3968: 58 62 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XbTRIM'...C..COM
-| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
-| 4000: 32 30 31 36 30 36 30 39 52 02 4a 4e 41 52 59 27 20160609R.JNARY'
-| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g
-| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
-| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C
-| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4.
-| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM
-| page 6 offset 20480
-| 0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0 ....$...........
-| 16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f b0 0f a8 0f a0 ................
-| 32: 0f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60 .........x.p.h.`
-| 48: 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 0f 28 0f 20 .X.P.H.@.8.0.(.
-| 64: 0f 18 0f 10 0f 08 0f 00 0e f8 0e f0 0e e8 0e e0 ................
-| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
-| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
-| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . ..............
-| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
-| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
-| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
-| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
-| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
-| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
-| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
-| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
-| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
-| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................
-| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................
-| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
-| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
-| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
-| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
-| page 7 offset 24576
-| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
-| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
-| page 8 offset 28672
-| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00 ................
-| 4048: 00 00 00 00 00 00 11 04 02 2b 69 6e 74 65 67 72 .........+integr
-| 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb
-| 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 5d 69 71 a5 uild....opti]iq.
-| end crash-41234e232809e7.db
-.testctrl prng_seed 1 db
-}]} {}
-
-do_catchsql_test 68.1 {
- PRAGMA reverse_unordered_selects=ON;
- INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
finish_test
DELETED ext/fts5/test/fts5corrupt4.test
Index: ext/fts5/test/fts5corrupt4.test
==================================================================
--- ext/fts5/test/fts5corrupt4.test
+++ /dev/null
@@ -1,61 +0,0 @@
-# 2019 May 16
-#
-# The author disclaims copyright to this source code. In place of
-# a legal notice, here is a blessing:
-#
-# May you do good and not evil.
-# May you find forgiveness for yourself and forgive others.
-# May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-#
-
-source [file join [file dirname [info script]] fts5_common.tcl]
-set testprefix fts5corrupt4
-
-# If SQLITE_ENABLE_FTS5 is defined, omit this file.
-ifcapable !fts5 {
- finish_test
- return
-}
-sqlite3_fts5_may_be_corrupt 1
-
-do_execsql_test 1.0 {
- CREATE VIRTUAL TABLE ttt USING fts5(a, b);
- INSERT INTO ttt
- VALUES('e ee eee e ee eee e ee eee', 'eee ee e e e ee eee ee ee');
- INSERT INTO ttt SELECT a||a, b||b FROM ttt;
- INSERT INTO ttt SELECT a||a, b||b FROM ttt;
-}
-
-proc mutate {blob i} {
- set o [expr {$i % [string length $blob]}]
- set a [string range $blob 0 $o-1]
- set b [string range $blob $o+1 end]
- set v [expr int(rand()*255) - 127]
- return "$a[binary format c $v]$b"
-}
-db func mutate mutate
-
-for {set j 1000} {$j <= 5000} {incr j 1000} {
- do_test 1.$j {
- for {set i 0} {$i < 1000} {incr i} {
- execsql {
- BEGIN;
- UPDATE ttt_data SET block = mutate(block, $i) WHERE id>10;
- }
- foreach sql {
- {SELECT snippet(ttt, -1, '.', '..', '[', ']'), * FROM ttt('e*')}
- {SELECT snippet(ttt, -1, '.', '..', '[', ']'), * FROM ttt('e* NOT ee*')}
- } {
- catch { execsql $sql }
- }
- execsql ROLLBACK
- }
- } {}
-}
-
-sqlite3_fts5_may_be_corrupt 0
-finish_test
-
Index: ext/fts5/test/fts5eb.test
==================================================================
--- ext/fts5/test/fts5eb.test
+++ ext/fts5/test/fts5eb.test
@@ -57,31 +57,14 @@
do_catchsql_test 2.1 {
SELECT fts5_expr()
} {1 {wrong number of arguments to function fts5_expr}}
-do_catchsql_test 2.2 {
+do_catchsql_test 2.1 {
SELECT fts5_expr_tcl()
} {1 {wrong number of arguments to function fts5_expr_tcl}}
-do_catchsql_test 2.3 {
- SELECT fts5_expr('')
-} {1 {fts5: syntax error near ""}}
-
-do_catchsql_test 2.4 {
- SELECT fts5_expr(NULL)
-} {1 {fts5: syntax error near ""}}
-
-do_catchsql_test 2.5 {
- SELECT fts5_expr(NULL, NULL)
-} {1 {parse error in ""}}
-
-for {set i 0} {$i < 255} {incr i} {
- do_test 2.6.$i {
- lindex [catchsql {sELECT fts5_expr(NULL, char($i));}] 0
- } 1
-}
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE e1 USING fts5(text, tokenize = 'porter unicode61');
INSERT INTO e1 VALUES ("just a few words with a / inside");
}
Index: ext/fts5/test/fts5faultB.test
==================================================================
--- ext/fts5/test/fts5faultB.test
+++ ext/fts5/test/fts5faultB.test
@@ -145,29 +145,7 @@
execsql { SELECT rowid FROM t1('^a OR ^b') }
} -test {
faultsim_test_result {0 {1 4}}
}
-#-------------------------------------------------------------------------
-# Test OOM injection in a query with two MATCH expressions
-#
-reset_db
-do_execsql_test 6.0 {
- CREATE VIRTUAL TABLE t1 USING fts5(a);
- INSERT INTO t1 VALUES('a b c d'); -- 1
- INSERT INTO t1 VALUES('d a b c'); -- 2
- INSERT INTO t1 VALUES('c d a b'); -- 3
- INSERT INTO t1 VALUES('b c d a'); -- 4
-}
-do_faultsim_test 6.1 -faults oom* -body {
- execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a' AND t1 MATCH 'b' }
-} -test {
- faultsim_test_result {0 {1 2 3 4}}
-}
-do_faultsim_test 6.2 -faults oom* -body {
- execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a OR b' AND t1 MATCH 'c OR d' }
-} -test {
- faultsim_test_result {0 {1 2 3 4}}
-}
-
finish_test
Index: ext/fts5/test/fts5full.test
==================================================================
--- ext/fts5/test/fts5full.test
+++ ext/fts5/test/fts5full.test
@@ -34,9 +34,9 @@
list [catch {
for {set i 0} {$i < 2500} {incr i} {
execsql { INSERT INTO x8 VALUES( rnddoc(5) ); }
}
} msg] $msg
-} {0 {}}
+} {1 {database or disk is full}}
finish_test
Index: ext/fts5/test/fts5integrity.test
==================================================================
--- ext/fts5/test/fts5integrity.test
+++ ext/fts5/test/fts5integrity.test
@@ -208,78 +208,6 @@
}
set ok
} {1000}
}
-#-------------------------------------------------------------------------
-#
-reset_db
-do_execsql_test 7.0 {
- PRAGMA encoding = 'UTF-16';
- CREATE VIRTUAL TABLE vt0 USING fts5(c0);
- INSERT INTO vt0 VALUES (x'46f0');
- SELECT quote(c0) FROM vt0;
-} {X'46F0'}
-do_execsql_test 7.1 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-do_execsql_test 7.2 {
- INSERT INTO vt0(vt0) VALUES('rebuild');
-}
-do_execsql_test 7.3 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-do_execsql_test 7.4 {
- UPDATE vt0 SET c0='';
-}
-do_execsql_test 7.5 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-
-#-------------------------------------------------------------------------
-# Ticket 7a458c2a5f4
-#
-reset_db
-do_execsql_test 8.0 {
- PRAGMA locking_mode = EXCLUSIVE;
- PRAGMA journal_mode = PERSIST;
- CREATE VIRTUAL TABLE vt0 USING fts5(c0);
-} {exclusive persist}
-do_execsql_test 8.1 {
- PRAGMA data_version
-} {1}
-do_execsql_test 8.2 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
- PRAGMA data_version;
-} {1}
-do_execsql_test 8.1 {
- INSERT INTO vt0(vt0, rank) VALUES('usermerge', 2);
-}
-
-#-------------------------------------------------------------------------
-# Ticket [771fe617]
-#
-reset_db
-do_execsql_test 9.0 {
- PRAGMA encoding = 'UTF16';
- CREATE VIRTUAL TABLE vt0 USING fts5(c0);
-}
-
-#explain_i { SELECT quote(SUBSTR(x'37', 0)); }
-#execsql { PRAGMA vdbe_trace = 1 }
-do_execsql_test 9.1.1 {
- SELECT quote(SUBSTR(x'37', 0));
-} {X'37'}
-do_execsql_test 9.1.2 {
- SELECT quote(x'37');
-} {X'37'}
-
-breakpoint
-do_execsql_test 9.2 {
- INSERT INTO vt0 VALUES (SUBSTR(x'37', 0));
--- INSERT INTO vt0 VALUES (x'37');
-}
-do_execsql_test 9.3 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-
finish_test
Index: ext/fts5/test/fts5matchinfo.test
==================================================================
--- ext/fts5/test/fts5matchinfo.test
+++ ext/fts5/test/fts5matchinfo.test
@@ -489,32 +489,6 @@
do_catchsql_test 14.2 {
SELECT matchinfo(x1, 'd') FROM x1('a b c');
} {1 {unrecognized matchinfo flag: d}}
-#-------------------------------------------------------------------------
-# Test using matchinfo() and similar on a non-full-text query
-#
-do_execsql_test 15.0 {
- CREATE VIRTUAL TABLE t1 USING fts5(x, y);
- INSERT INTO t1 VALUES('a', 'b');
- INSERT INTO t1 VALUES('c', 'd');
-}
-
-do_execsql_test 15.1 {
- SELECT quote(matchinfo(t1, 'n')) FROM t1 LIMIT 1;
-} {X'02000000'}
-
-do_execsql_test 15.2 {
- DELETE FROM t1_content WHERE rowid=1;
- SELECT quote(matchinfo(t1, 'n')) FROM t1 LIMIT 1;
-} {X'02000000'}
-
-fts5_aux_test_functions db
-do_execsql_test 15.3 {
- SELECT fts5_test_all(t1) FROM t1 LIMIT 1;
-} {
- {columnsize {0 0} columntext {c d} columntotalsize {2 2} poslist {} tokenize {c d} rowcount 2}
-}
-
finish_test
-
DELETED ext/fts5/test/fts5misc.test
Index: ext/fts5/test/fts5misc.test
==================================================================
--- ext/fts5/test/fts5misc.test
+++ /dev/null
@@ -1,327 +0,0 @@
-# 2019 September 02
-#
-# The author disclaims copyright to this source code. In place of
-# a legal notice, here is a blessing:
-#
-# May you do good and not evil.
-# May you find forgiveness for yourself and forgive others.
-# May you share freely, never taking more than you give.
-#
-#*************************************************************************
-# This file implements regression tests for SQLite library. The
-# focus of this script is testing the FTS5 module.
-#
-
-source [file join [file dirname [info script]] fts5_common.tcl]
-set testprefix fts5misc
-
-# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
-ifcapable !fts5 {
- finish_test
- return
-}
-
-do_execsql_test 1.0 {
- CREATE VIRTUAL TABLE t1 USING fts5(a);
-}
-
-do_catchsql_test 1.1.1 {
- SELECT highlight(t1, 4, '', '') FROM t1('*');
-} {1 {unknown special query: }}
-do_catchsql_test 1.1.2 {
- SELECT a FROM t1
- WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*'));
-} {1 {unknown special query: }}
-
-do_catchsql_test 1.2.1 {
- SELECT highlight(t1, 4, '', '') FROM t1('*id');
-} {0 {{}}}
-
-do_catchsql_test 1.2.2 {
- SELECT a FROM t1
- WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*id'));
-} {0 {}}
-
-do_catchsql_test 1.3.1 {
- SELECT highlight(t1, 4, '', '') FROM t1('*reads');
-} {1 {no such cursor: 1}}
-
-do_catchsql_test 1.3.2 {
- SELECT a FROM t1
- WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*reads'));
-} {1 {no such cursor: 1}}
-
-db close
-sqlite3 db test.db
-
-do_catchsql_test 1.3.3 {
- SELECT a FROM t1
- WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*reads'));
-} {1 {no such cursor: 1}}
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 2.0 {
- CREATE TABLE t0(c0);
- CREATE VIRTUAL TABLE vt0 USING fts5(c0);
-}
-do_execsql_test 2.1.1 {
- BEGIN TRANSACTION;
- INSERT INTO vt0(c0) VALUES ('xyz');
-}
-do_execsql_test 2.1.2 {
- ALTER TABLE t0 ADD COLUMN c5;
-}
-do_execsql_test 2.1.3 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-do_execsql_test 2.1.4 {
- INSERT INTO vt0(c0) VALUES ('abc');
- COMMIT
-}
-do_execsql_test 2.1.5 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-
-reset_db
-do_execsql_test 2.2.1 {
- CREATE TABLE t0(c0);
- CREATE VIRTUAL TABLE vt0 USING fts5(c0);
- BEGIN TRANSACTION;
- INSERT INTO vt0(c0) VALUES ('xyz');
-}
-
-breakpoint
-do_execsql_test 2.2.2 {
- ALTER TABLE t0 RENAME TO t1;
-}
-do_execsql_test 2.2.3 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-do_execsql_test 2.2.4 {
- INSERT INTO vt0(c0) VALUES ('abc');
- COMMIT;
-}
-do_execsql_test 2.2.5 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 3.0 {
- CREATE VIRTUAL TABLE vt0 USING fts5(a);
- PRAGMA reverse_unordered_selects = true;
- INSERT INTO vt0 VALUES('365062398'), (0), (0);
- INSERT INTO vt0(vt0, rank) VALUES('pgsz', '38');
-}
-do_execsql_test 3.1 {
- UPDATE vt0 SET a = 399905135; -- unexpected: database disk image is malformed
-}
-do_execsql_test 3.2 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 4.0 {
- CREATE VIRTUAL TABLE vt0 USING fts5(c0);
- INSERT INTO vt0(c0) VALUES ('xyz');
-}
-
-do_execsql_test 4.1 {
- BEGIN;
- INSERT INTO vt0(c0) VALUES ('abc');
- INSERT INTO vt0(vt0) VALUES('rebuild');
- COMMIT;
-}
-
-do_execsql_test 4.2 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-
-do_execsql_test 4.3 {
- BEGIN;
- INSERT INTO vt0(vt0) VALUES('rebuild');
- INSERT INTO vt0(vt0) VALUES('rebuild');
- COMMIT;
-}
-
-do_execsql_test 4.4 {
- INSERT INTO vt0(vt0) VALUES('integrity-check');
-}
-
-#-------------------------------------------------------------------------
-# Ticket [81a7f7b9].
-#
-reset_db
-do_execsql_test 5.0 {
- CREATE VIRTUAL TABLE vt0 USING fts5(c0, c1);
- INSERT INTO vt0(vt0, rank) VALUES('pgsz', '65536');
- WITH s(i) AS (
- SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1236
- )
- INSERT INTO vt0(c0) SELECT '0' FROM s;
-} {}
-
-do_execsql_test 5.1 {
- UPDATE vt0 SET c1 = 'T,D&p^y/7#3*v t1.x
} {
@@ -44,11 +44,11 @@
do_eqp_test 1.3 {
SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
} {
QUERY PLAN
- |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
+ |--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
`--USE TEMP B-TREE FOR ORDER BY
}
do_eqp_test 1.4 {
SELECT * FROM f1 ORDER BY rank
@@ -58,8 +58,8 @@
`--USE TEMP B-TREE FOR ORDER BY
}
do_eqp_test 1.5 {
SELECT * FROM f1 WHERE rank MATCH ?
-} {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:r}
+} {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}
finish_test
Index: ext/fts5/test/fts5rank.test
==================================================================
--- ext/fts5/test/fts5rank.test
+++ ext/fts5/test/fts5rank.test
@@ -160,24 +160,6 @@
do_execsql_test 5.1 {
SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
} {30 31 32 33 34 35 36 37 38 39 40}
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 6.0 {
- CREATE VIRTUAL TABLE "My.Table" USING fts5(Text);
-
- INSERT INTO "My.Table" VALUES ('hello this is a test');
- INSERT INTO "My.Table" VALUES ('of trying to order by');
- INSERT INTO "My.Table" VALUES ('rank on an fts5 table');
- INSERT INTO "My.Table" VALUES ('that have periods in');
- INSERT INTO "My.Table" VALUES ('the table names.');
- INSERT INTO "My.Table" VALUES ('table table table');
-}
-do_execsql_test 6.1 {
- SELECT * FROM "My.Table" WHERE Text MATCH 'table' ORDER BY rank;
-} {
- {table table table} {the table names.} {rank on an fts5 table}
-}
-
finish_test
DELETED ext/fts5/test/fts5savepoint.test
Index: ext/fts5/test/fts5savepoint.test
==================================================================
--- ext/fts5/test/fts5savepoint.test
+++ /dev/null
@@ -1,85 +0,0 @@
-# 2019 Dec 26
-#
-# The author disclaims copyright to this source code. In place of
-# a legal notice, here is a blessing:
-#
-# May you do good and not evil.
-# May you find forgiveness for yourself and forgive others.
-# May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-
-source [file join [file dirname [info script]] fts5_common.tcl]
-set testprefix fts5savepoint
-
-# If SQLITE_ENABLE_FTS5 is defined, omit this file.
-ifcapable !fts5 {
- finish_test
- return
-}
-
-do_execsql_test 1.0 {
- CREATE VIRTUAL TABLE ft USING fts5(c);
- BEGIN;
- SAVEPOINT one;
- INSERT INTO ft VALUES('a');
- SAVEPOINT two;
- INSERT INTO ft VALUES('b');
- RELEASE two;
- SAVEPOINT four;
- INSERT INTO ft VALUES('c');
- RELEASE four;
- SAVEPOINT three;
- INSERT INTO ft VALUES('d');
- ROLLBACK TO three;
- COMMIT;
- SELECT * FROM ft
-} {a b c}
-
-reset_db
-do_catchsql_test 2.0 {
- CREATE VIRTUAL TABLE ft1 USING fts5(c);
- CREATE VIRTUAL TABLE ft2 USING fts5(c);
- DROP TABLE ft2_idx;
- BEGIN;
- INSERT INTO ft2 VALUES('a');
- INSERT INTO ft1 VALUES('a');
- SAVEPOINT two;
- INSERT INTO ft1 VALUES('b');
- COMMIT;
-} {1 {SQL logic error}}
-
-reset_db
-ifcapable fts3 {
- do_execsql_test 3.0 {
- CREATE VIRTUAL TABLE vt0 USING fts5(c0);
- CREATE VIRTUAL TABLE vt1 USING fts4(c0);
- INSERT INTO vt1(c0) VALUES(0);
- }
-
- do_execsql_test 3.1 {
- BEGIN;
- UPDATE vt1 SET c0 = 0;
- INSERT INTO vt1(c0) VALUES (0), (0);
- UPDATE vt0 SET c0 = 0;
- INSERT INTO vt1(c0) VALUES (0);
- UPDATE vt1 SET c0 = 0;
- INSERT INTO vt1(vt1) VALUES('automerge=1');
- UPDATE vt1 SET c0 = 0;
- }
-
- do_catchsql_test 3.2 {
- DROP TABLE vt1;
- } {1 {SQL logic error}}
-
- do_execsql_test 3.3 {
- SAVEPOINT x;
- INSERT INTO vt0 VALUES('x');
- COMMIT;
- INSERT INTO vt0(vt0) VALUES('integrity-check');
- }
-}
-
-finish_test
-
Index: ext/fts5/test/fts5simple.test
==================================================================
--- ext/fts5/test/fts5simple.test
+++ ext/fts5/test/fts5simple.test
@@ -465,19 +465,6 @@
DELETE FROM x1 WHERE rowid=11111;
INSERT INTO x1(x1) VALUES('integrity-check');
SELECT rowid FROM x1($doc);
} {11112}
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 22.0 {
- CREATE VIRTUAL TABLE x1 USING fts5(x);
- INSERT INTO x1(x) VALUES('a b c');
- INSERT INTO x1(x) VALUES('x y z');
- INSERT INTO x1(x) VALUES('c b a');
- INSERT INTO x1(x) VALUES('z y x');
-}
-
-do_catchsql_test 22.1 {SELECT * FROM x1('')} {1 {fts5: syntax error near ""}}
-do_catchsql_test 22.2 {SELECT * FROM x1(NULL)} {1 {fts5: syntax error near ""}}
-
finish_test
Index: ext/icu/icu.c
==================================================================
--- ext/icu/icu.c
+++ ext/icu/icu.c
@@ -497,31 +497,30 @@
/*
** Register the ICU extension functions with database db.
*/
int sqlite3IcuInit(sqlite3 *db){
-# define SQLITEICU_EXTRAFLAGS (SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS)
static const struct IcuScalar {
const char *zName; /* Function name */
unsigned char nArg; /* Number of arguments */
- unsigned int enc; /* Optimal text encoding */
+ unsigned short enc; /* Optimal text encoding */
unsigned char iContext; /* sqlite3_user_data() context */
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
} scalars[] = {
- {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation},
+ {"icu_load_collation", 2, SQLITE_UTF8, 1, icuLoadCollation},
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
- {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc},
- {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
- {"lower", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
- {"upper", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16},
- {"upper", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16},
- {"lower", 1, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
- {"lower", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
- {"upper", 1, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16},
- {"upper", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16},
- {"like", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuLikeFunc},
- {"like", 3, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuLikeFunc},
+ {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc},
+ {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
+ {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
+ {"upper", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
+ {"upper", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
+ {"lower", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
+ {"lower", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
+ {"upper", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
+ {"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
+ {"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc},
+ {"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc},
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
};
int rc = SQLITE_OK;
int i;
Index: ext/lsm1/Makefile
==================================================================
--- ext/lsm1/Makefile
+++ ext/lsm1/Makefile
@@ -41,14 +41,14 @@
$(LSMDIR)/lsm-test/lsmtest_util.c $(LSMDIR)/lsm-test/lsmtest_win32.c
# all: lsm.so
-LSMOPTS += -fPIC -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB
+LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB
lsm.so: $(LSMOBJ)
- $(TCCX) -shared -fPIC -o lsm.so $(LSMOBJ)
+ $(TCCX) -shared -o lsm.so $(LSMOBJ)
%.o: $(LSMDIR)/%.c $(LSMHDR) sqlite3.h
$(TCCX) $(LSMOPTS) -c $<
lsmtest$(EXE): $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) sqlite3.o
Index: ext/lsm1/lsm_vtab.c
==================================================================
--- ext/lsm1/lsm_vtab.c
+++ ext/lsm1/lsm_vtab.c
@@ -840,11 +840,11 @@
int omit1 = 0;
int omit2 = 0;
const struct sqlite3_index_constraint *pConstraint;
pConstraint = pIdxInfo->aConstraint;
- for(i=0; inConstraint; i++, pConstraint++){
+ for(i=0; inConstraint && idxNum<16; i++, pConstraint++){
if( pConstraint->usable==0 ) continue;
if( pConstraint->iColumn!=0 ) continue;
switch( pConstraint->op ){
case SQLITE_INDEX_CONSTRAINT_EQ: {
if( idxNum>0 ){
Index: ext/lsm1/test/lsm1_simple.test
==================================================================
--- ext/lsm1/test/lsm1_simple.test
+++ ext/lsm1/test/lsm1_simple.test
@@ -86,67 +86,8 @@
SELECT quote(a), quote(b), quote(c), quote(d), '|' FROM x1;
} {'12' NULL 3.25 -559281390 | '15' 11 22 33 | '8' 'banjo' X'333231' NULL |}
do_execsql_test 211 {
SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1;
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |}
-do_execsql_test 212 {
- SELECT quote(a), quote(lsm1_key), quote(lsm1_value) FROM x1 WHERE a='12';
-} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB'}
-
-#-------------------------------------------------------------------------
-reset_db
-forcedelete testlsm.db
-load_lsm1_vtab db
-do_execsql_test 300 {
- CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b,c,d);
-}
-do_eqp_test 310 {
- SELECT * FROM x1 WHERE a=?
-} {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:}
-
-do_eqp_test 320 {
- SELECT * FROM x1 WHERE a>?
-} {SCAN TABLE x1 VIRTUAL TABLE INDEX 2:}
-
-do_eqp_test 330 {
- SELECT * FROM x1 WHERE a
-} {SCAN TABLE x1 VIRTUAL TABLE INDEX 3:}
-do_eqp_test 340 {
- SELECT * FROM x1 WHERE a BETWEEN ? AND ?
-} {SCAN TABLE x1 VIRTUAL TABLE INDEX 1:}
-
-#-------------------------------------------------------------------------
-reset_db
-forcedelete testlsm.db
-load_lsm1_vtab db
-do_execsql_test 400 {
- CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b);
- INSERT INTO x1 VALUES('one', 1);
- INSERT INTO x1 VALUES('two', 2);
- INSERT INTO x1 VALUES('three', 3);
- INSERT INTO x1 VALUES('four', 4);
- INSERT INTO x1 VALUES('five', 5);
-}
-do_execsql_test 410 {
- SELECT b FROM x1 WHERE a = 'two'
-} {2}
-do_execsql_test 411 {
- SELECT b FROM x1 WHERE a = 'one'
-} {1}
-do_execsql_test 412 {
- SELECT b FROM x1 WHERE a = 'five'
-} {5}
-
-do_execsql_test 420 {
- SELECT b FROM x1 WHERE a BETWEEN 'one' AND 'three';
-} {1 3}
-do_execsql_test 421 {
- SELECT b FROM x1 WHERE a BETWEEN 'five' AND 'two';
-} {5 4 1 3 2}
-do_execsql_test 421 {
- SELECT b FROM x1 WHERE a > 'five';
-} {4 1 3 2}
-do_execsql_test 421 {
- SELECT b FROM x1 WHERE a <= 'three';
-} {3 1 4 5}
+
finish_test
Index: ext/misc/amatch.c
==================================================================
--- ext/misc/amatch.c
+++ ext/misc/amatch.c
@@ -898,11 +898,10 @@
rc = SQLITE_ERROR;
}else{
rc = amatchLoadRules(db, pNew, pzErr);
}
if( rc==SQLITE_OK ){
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(word,distance,language,"
"command HIDDEN,nword HIDDEN)"
);
#define AMATCH_COL_WORD 0
Index: ext/misc/blobio.c
==================================================================
--- ext/misc/blobio.c
+++ ext/misc/blobio.c
@@ -74,11 +74,11 @@
}
rc = sqlite3_blob_read(pBlob, aData, nData, iOfst);
sqlite3_blob_close(pBlob);
if( rc ){
sqlite3_free(aData);
- sqlite3_result_error(context, "BLOB read failed", -1);
+ sqlite3_result_error(context, "BLOB write failed", -1);
}else{
sqlite3_result_blob(context, aData, nData, sqlite3_free);
}
}
Index: ext/misc/carray.c
==================================================================
--- ext/misc/carray.c
+++ ext/misc/carray.c
@@ -22,11 +22,11 @@
** sqlite3_bind_pointer() interface with a pointer type of "carray".
** For example:
**
** static int aX[] = { 53, 9, 17, 2231, 4, 99 };
** int i = sqlite3_bind_parameter_index(pStmt, "$ptr");
-** sqlite3_bind_pointer(pStmt, i, aX, "carray", 0);
+** sqlite3_bind_value(pStmt, i, aX, "carray", 0);
**
** There is an optional third parameter to determine the datatype of
** the C-language array. Allowed values of the third parameter are
** 'int32', 'int64', 'double', 'char*'. Example:
**
Index: ext/misc/completion.c
==================================================================
--- ext/misc/completion.c
+++ ext/misc/completion.c
@@ -116,11 +116,10 @@
#define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */
#define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */
#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x("
" candidate TEXT,"
" prefix TEXT HIDDEN,"
" wholeline TEXT HIDDEN,"
Index: ext/misc/compress.c
==================================================================
--- ext/misc/compress.c
+++ ext/misc/compress.c
@@ -117,15 +117,13 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "compress", 1,
- SQLITE_UTF8 | SQLITE_INNOCUOUS,
- 0, compressFunc, 0, 0);
+ rc = sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0,
+ compressFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "uncompress", 1,
- SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
- 0, uncompressFunc, 0, 0);
+ rc = sqlite3_create_function(db, "uncompress", 1, SQLITE_UTF8, 0,
+ uncompressFunc, 0, 0);
}
return rc;
}
Index: ext/misc/csv.c
==================================================================
--- ext/misc/csv.c
+++ ext/misc/csv.c
@@ -630,19 +630,10 @@
goto csvtab_connect_error;
}
for(i=0; i
-#include
-
-#define DBDATA_PADDING_BYTES 100
-
-typedef struct DbdataTable DbdataTable;
-typedef struct DbdataCursor DbdataCursor;
-
-/* Cursor object */
-struct DbdataCursor {
- sqlite3_vtab_cursor base; /* Base class. Must be first */
- sqlite3_stmt *pStmt; /* For fetching database pages */
-
- int iPgno; /* Current page number */
- u8 *aPage; /* Buffer containing page */
- int nPage; /* Size of aPage[] in bytes */
- int nCell; /* Number of cells on aPage[] */
- int iCell; /* Current cell number */
- int bOnePage; /* True to stop after one page */
- int szDb;
- sqlite3_int64 iRowid;
-
- /* Only for the sqlite_dbdata table */
- u8 *pRec; /* Buffer containing current record */
- int nRec; /* Size of pRec[] in bytes */
- int nHdr; /* Size of header in bytes */
- int iField; /* Current field number */
- u8 *pHdrPtr;
- u8 *pPtr;
-
- sqlite3_int64 iIntkey; /* Integer key value */
-};
-
-/* Table object */
-struct DbdataTable {
- sqlite3_vtab base; /* Base class. Must be first */
- sqlite3 *db; /* The database connection */
- sqlite3_stmt *pStmt; /* For fetching database pages */
- int bPtr; /* True for sqlite3_dbptr table */
-};
-
-/* Column and schema definitions for sqlite_dbdata */
-#define DBDATA_COLUMN_PGNO 0
-#define DBDATA_COLUMN_CELL 1
-#define DBDATA_COLUMN_FIELD 2
-#define DBDATA_COLUMN_VALUE 3
-#define DBDATA_COLUMN_SCHEMA 4
-#define DBDATA_SCHEMA \
- "CREATE TABLE x(" \
- " pgno INTEGER," \
- " cell INTEGER," \
- " field INTEGER," \
- " value ANY," \
- " schema TEXT HIDDEN" \
- ")"
-
-/* Column and schema definitions for sqlite_dbptr */
-#define DBPTR_COLUMN_PGNO 0
-#define DBPTR_COLUMN_CHILD 1
-#define DBPTR_COLUMN_SCHEMA 2
-#define DBPTR_SCHEMA \
- "CREATE TABLE x(" \
- " pgno INTEGER," \
- " child INTEGER," \
- " schema TEXT HIDDEN" \
- ")"
-
-/*
-** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual
-** table.
-*/
-static int dbdataConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- DbdataTable *pTab = 0;
- int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
-
- if( rc==SQLITE_OK ){
- pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
- if( pTab==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memset(pTab, 0, sizeof(DbdataTable));
- pTab->db = db;
- pTab->bPtr = (pAux!=0);
- }
- }
-
- *ppVtab = (sqlite3_vtab*)pTab;
- return rc;
-}
-
-/*
-** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
-*/
-static int dbdataDisconnect(sqlite3_vtab *pVtab){
- DbdataTable *pTab = (DbdataTable*)pVtab;
- if( pTab ){
- sqlite3_finalize(pTab->pStmt);
- sqlite3_free(pVtab);
- }
- return SQLITE_OK;
-}
-
-/*
-** This function interprets two types of constraints:
-**
-** schema=?
-** pgno=?
-**
-** If neither are present, idxNum is set to 0. If schema=? is present,
-** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
-** in idxNum is set.
-**
-** If both parameters are present, schema is in position 0 and pgno in
-** position 1.
-*/
-static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
- DbdataTable *pTab = (DbdataTable*)tab;
- int i;
- int iSchema = -1;
- int iPgno = -1;
- int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);
-
- for(i=0; inConstraint; i++){
- struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
- if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
- if( p->iColumn==colSchema ){
- if( p->usable==0 ) return SQLITE_CONSTRAINT;
- iSchema = i;
- }
- if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
- iPgno = i;
- }
- }
- }
-
- if( iSchema>=0 ){
- pIdx->aConstraintUsage[iSchema].argvIndex = 1;
- pIdx->aConstraintUsage[iSchema].omit = 1;
- }
- if( iPgno>=0 ){
- pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
- pIdx->aConstraintUsage[iPgno].omit = 1;
- pIdx->estimatedCost = 100;
- pIdx->estimatedRows = 50;
-
- if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
- int iCol = pIdx->aOrderBy[0].iColumn;
- if( pIdx->nOrderBy==1 ){
- pIdx->orderByConsumed = (iCol==0 || iCol==1);
- }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
- pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
- }
- }
-
- }else{
- pIdx->estimatedCost = 100000000;
- pIdx->estimatedRows = 1000000000;
- }
- pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
- return SQLITE_OK;
-}
-
-/*
-** Open a new sqlite_dbdata or sqlite_dbptr cursor.
-*/
-static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
- DbdataCursor *pCsr;
-
- pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
- if( pCsr==0 ){
- return SQLITE_NOMEM;
- }else{
- memset(pCsr, 0, sizeof(DbdataCursor));
- pCsr->base.pVtab = pVTab;
- }
-
- *ppCursor = (sqlite3_vtab_cursor *)pCsr;
- return SQLITE_OK;
-}
-
-/*
-** Restore a cursor object to the state it was in when first allocated
-** by dbdataOpen().
-*/
-static void dbdataResetCursor(DbdataCursor *pCsr){
- DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
- if( pTab->pStmt==0 ){
- pTab->pStmt = pCsr->pStmt;
- }else{
- sqlite3_finalize(pCsr->pStmt);
- }
- pCsr->pStmt = 0;
- pCsr->iPgno = 1;
- pCsr->iCell = 0;
- pCsr->iField = 0;
- pCsr->bOnePage = 0;
- sqlite3_free(pCsr->aPage);
- sqlite3_free(pCsr->pRec);
- pCsr->pRec = 0;
- pCsr->aPage = 0;
-}
-
-/*
-** Close an sqlite_dbdata or sqlite_dbptr cursor.
-*/
-static int dbdataClose(sqlite3_vtab_cursor *pCursor){
- DbdataCursor *pCsr = (DbdataCursor*)pCursor;
- dbdataResetCursor(pCsr);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-/*
-** Utility methods to decode 16 and 32-bit big-endian unsigned integers.
-*/
-static unsigned int get_uint16(unsigned char *a){
- return (a[0]<<8)|a[1];
-}
-static unsigned int get_uint32(unsigned char *a){
- return ((unsigned int)a[0]<<24)
- | ((unsigned int)a[1]<<16)
- | ((unsigned int)a[2]<<8)
- | ((unsigned int)a[3]);
-}
-
-/*
-** Load page pgno from the database via the sqlite_dbpage virtual table.
-** If successful, set (*ppPage) to point to a buffer containing the page
-** data, (*pnPage) to the size of that buffer in bytes and return
-** SQLITE_OK. In this case it is the responsibility of the caller to
-** eventually free the buffer using sqlite3_free().
-**
-** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
-** return an SQLite error code.
-*/
-static int dbdataLoadPage(
- DbdataCursor *pCsr, /* Cursor object */
- unsigned int pgno, /* Page number of page to load */
- u8 **ppPage, /* OUT: pointer to page buffer */
- int *pnPage /* OUT: Size of (*ppPage) in bytes */
-){
- int rc2;
- int rc = SQLITE_OK;
- sqlite3_stmt *pStmt = pCsr->pStmt;
-
- *ppPage = 0;
- *pnPage = 0;
- sqlite3_bind_int64(pStmt, 2, pgno);
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- int nCopy = sqlite3_column_bytes(pStmt, 0);
- if( nCopy>0 ){
- u8 *pPage;
- pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
- if( pPage==0 ){
- rc = SQLITE_NOMEM;
- }else{
- const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
- memcpy(pPage, pCopy, nCopy);
- memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
- }
- *ppPage = pPage;
- *pnPage = nCopy;
- }
- }
- rc2 = sqlite3_reset(pStmt);
- if( rc==SQLITE_OK ) rc = rc2;
-
- return rc;
-}
-
-/*
-** Read a varint. Put the value in *pVal and return the number of bytes.
-*/
-static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
- sqlite3_int64 v = 0;
- int i;
- for(i=0; i<8; i++){
- v = (v<<7) + (z[i]&0x7f);
- if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
- }
- v = (v<<8) + (z[i]&0xff);
- *pVal = v;
- return 9;
-}
-
-/*
-** Return the number of bytes of space used by an SQLite value of type
-** eType.
-*/
-static int dbdataValueBytes(int eType){
- switch( eType ){
- case 0: case 8: case 9:
- case 10: case 11:
- return 0;
- case 1:
- return 1;
- case 2:
- return 2;
- case 3:
- return 3;
- case 4:
- return 4;
- case 5:
- return 6;
- case 6:
- case 7:
- return 8;
- default:
- if( eType>0 ){
- return ((eType-12) / 2);
- }
- return 0;
- }
-}
-
-/*
-** Load a value of type eType from buffer pData and use it to set the
-** result of context object pCtx.
-*/
-static void dbdataValue(
- sqlite3_context *pCtx,
- int eType,
- u8 *pData,
- int nData
-){
- if( eType>=0 && dbdataValueBytes(eType)<=nData ){
- switch( eType ){
- case 0:
- case 10:
- case 11:
- sqlite3_result_null(pCtx);
- break;
-
- case 8:
- sqlite3_result_int(pCtx, 0);
- break;
- case 9:
- sqlite3_result_int(pCtx, 1);
- break;
-
- case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
- sqlite3_uint64 v = (signed char)pData[0];
- pData++;
- switch( eType ){
- case 7:
- case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
- case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
- case 4: v = (v<<8) + pData[0]; pData++;
- case 3: v = (v<<8) + pData[0]; pData++;
- case 2: v = (v<<8) + pData[0]; pData++;
- }
-
- if( eType==7 ){
- double r;
- memcpy(&r, &v, sizeof(r));
- sqlite3_result_double(pCtx, r);
- }else{
- sqlite3_result_int64(pCtx, (sqlite3_int64)v);
- }
- break;
- }
-
- default: {
- int n = ((eType-12) / 2);
- if( eType % 2 ){
- sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
- }else{
- sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
- }
- }
- }
- }
-}
-
-/*
-** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
-*/
-static int dbdataNext(sqlite3_vtab_cursor *pCursor){
- DbdataCursor *pCsr = (DbdataCursor*)pCursor;
- DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
-
- pCsr->iRowid++;
- while( 1 ){
- int rc;
- int iOff = (pCsr->iPgno==1 ? 100 : 0);
- int bNextPage = 0;
-
- if( pCsr->aPage==0 ){
- while( 1 ){
- if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
- rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
- if( rc!=SQLITE_OK ) return rc;
- if( pCsr->aPage ) break;
- pCsr->iPgno++;
- }
- pCsr->iCell = pTab->bPtr ? -2 : 0;
- pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
- }
-
- if( pTab->bPtr ){
- if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
- pCsr->iCell = pCsr->nCell;
- }
- pCsr->iCell++;
- if( pCsr->iCell>=pCsr->nCell ){
- sqlite3_free(pCsr->aPage);
- pCsr->aPage = 0;
- if( pCsr->bOnePage ) return SQLITE_OK;
- pCsr->iPgno++;
- }else{
- return SQLITE_OK;
- }
- }else{
- /* If there is no record loaded, load it now. */
- if( pCsr->pRec==0 ){
- int bHasRowid = 0;
- int nPointer = 0;
- sqlite3_int64 nPayload = 0;
- sqlite3_int64 nHdr = 0;
- int iHdr;
- int U, X;
- int nLocal;
-
- switch( pCsr->aPage[iOff] ){
- case 0x02:
- nPointer = 4;
- break;
- case 0x0a:
- break;
- case 0x0d:
- bHasRowid = 1;
- break;
- default:
- /* This is not a b-tree page with records on it. Continue. */
- pCsr->iCell = pCsr->nCell;
- break;
- }
-
- if( pCsr->iCell>=pCsr->nCell ){
- bNextPage = 1;
- }else{
-
- iOff += 8 + nPointer + pCsr->iCell*2;
- if( iOff>pCsr->nPage ){
- bNextPage = 1;
- }else{
- iOff = get_uint16(&pCsr->aPage[iOff]);
- }
-
- /* For an interior node cell, skip past the child-page number */
- iOff += nPointer;
-
- /* Load the "byte of payload including overflow" field */
- if( bNextPage || iOff>pCsr->nPage ){
- bNextPage = 1;
- }else{
- iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
- }
-
- /* If this is a leaf intkey cell, load the rowid */
- if( bHasRowid && !bNextPage && iOffnPage ){
- iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
- }
-
- /* Figure out how much data to read from the local page */
- U = pCsr->nPage;
- if( bHasRowid ){
- X = U-35;
- }else{
- X = ((U-12)*64/255)-23;
- }
- if( nPayload<=X ){
- nLocal = nPayload;
- }else{
- int M, K;
- M = ((U-12)*32/255)-23;
- K = M+((nPayload-M)%(U-4));
- if( K<=X ){
- nLocal = K;
- }else{
- nLocal = M;
- }
- }
-
- if( bNextPage || nLocal+iOff>pCsr->nPage ){
- bNextPage = 1;
- }else{
-
- /* Allocate space for payload. And a bit more to catch small buffer
- ** overruns caused by attempting to read a varint or similar from
- ** near the end of a corrupt record. */
- pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
- if( pCsr->pRec==0 ) return SQLITE_NOMEM;
- memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
- pCsr->nRec = nPayload;
-
- /* Load the nLocal bytes of payload */
- memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
- iOff += nLocal;
-
- /* Load content from overflow pages */
- if( nPayload>nLocal ){
- sqlite3_int64 nRem = nPayload - nLocal;
- unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
- while( nRem>0 ){
- u8 *aOvfl = 0;
- int nOvfl = 0;
- int nCopy;
- rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
- assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
- if( rc!=SQLITE_OK ) return rc;
- if( aOvfl==0 ) break;
-
- nCopy = U-4;
- if( nCopy>nRem ) nCopy = nRem;
- memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
- nRem -= nCopy;
-
- pgnoOvfl = get_uint32(aOvfl);
- sqlite3_free(aOvfl);
- }
- }
-
- iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
- pCsr->nHdr = nHdr;
- pCsr->pHdrPtr = &pCsr->pRec[iHdr];
- pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
- pCsr->iField = (bHasRowid ? -1 : 0);
- }
- }
- }else{
- pCsr->iField++;
- if( pCsr->iField>0 ){
- sqlite3_int64 iType;
- if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
- bNextPage = 1;
- }else{
- pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
- pCsr->pPtr += dbdataValueBytes(iType);
- }
- }
- }
-
- if( bNextPage ){
- sqlite3_free(pCsr->aPage);
- sqlite3_free(pCsr->pRec);
- pCsr->aPage = 0;
- pCsr->pRec = 0;
- if( pCsr->bOnePage ) return SQLITE_OK;
- pCsr->iPgno++;
- }else{
- if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
- return SQLITE_OK;
- }
-
- /* Advance to the next cell. The next iteration of the loop will load
- ** the record and so on. */
- sqlite3_free(pCsr->pRec);
- pCsr->pRec = 0;
- pCsr->iCell++;
- }
- }
- }
-
- assert( !"can't get here" );
- return SQLITE_OK;
-}
-
-/*
-** Return true if the cursor is at EOF.
-*/
-static int dbdataEof(sqlite3_vtab_cursor *pCursor){
- DbdataCursor *pCsr = (DbdataCursor*)pCursor;
- return pCsr->aPage==0;
-}
-
-/*
-** Determine the size in pages of database zSchema (where zSchema is
-** "main", "temp" or the name of an attached database) and set
-** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
-** an SQLite error code.
-*/
-static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
- DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
- char *zSql = 0;
- int rc, rc2;
- sqlite3_stmt *pStmt = 0;
-
- zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
- if( zSql==0 ) return SQLITE_NOMEM;
- rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
- pCsr->szDb = sqlite3_column_int(pStmt, 0);
- }
- rc2 = sqlite3_finalize(pStmt);
- if( rc==SQLITE_OK ) rc = rc2;
- return rc;
-}
-
-/*
-** xFilter method for sqlite_dbdata and sqlite_dbptr.
-*/
-static int dbdataFilter(
- sqlite3_vtab_cursor *pCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- DbdataCursor *pCsr = (DbdataCursor*)pCursor;
- DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
- int rc = SQLITE_OK;
- const char *zSchema = "main";
-
- dbdataResetCursor(pCsr);
- assert( pCsr->iPgno==1 );
- if( idxNum & 0x01 ){
- zSchema = (const char*)sqlite3_value_text(argv[0]);
- }
- if( idxNum & 0x02 ){
- pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
- pCsr->bOnePage = 1;
- }else{
- pCsr->nPage = dbdataDbsize(pCsr, zSchema);
- rc = dbdataDbsize(pCsr, zSchema);
- }
-
- if( rc==SQLITE_OK ){
- if( pTab->pStmt ){
- pCsr->pStmt = pTab->pStmt;
- pTab->pStmt = 0;
- }else{
- rc = sqlite3_prepare_v2(pTab->db,
- "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
- &pCsr->pStmt, 0
- );
- }
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
- }else{
- pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
- }
- if( rc==SQLITE_OK ){
- rc = dbdataNext(pCursor);
- }
- return rc;
-}
-
-/*
-** Return a column for the sqlite_dbdata or sqlite_dbptr table.
-*/
-static int dbdataColumn(
- sqlite3_vtab_cursor *pCursor,
- sqlite3_context *ctx,
- int i
-){
- DbdataCursor *pCsr = (DbdataCursor*)pCursor;
- DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
- if( pTab->bPtr ){
- switch( i ){
- case DBPTR_COLUMN_PGNO:
- sqlite3_result_int64(ctx, pCsr->iPgno);
- break;
- case DBPTR_COLUMN_CHILD: {
- int iOff = pCsr->iPgno==1 ? 100 : 0;
- if( pCsr->iCell<0 ){
- iOff += 8;
- }else{
- iOff += 12 + pCsr->iCell*2;
- if( iOff>pCsr->nPage ) return SQLITE_OK;
- iOff = get_uint16(&pCsr->aPage[iOff]);
- }
- if( iOff<=pCsr->nPage ){
- sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
- }
- break;
- }
- }
- }else{
- switch( i ){
- case DBDATA_COLUMN_PGNO:
- sqlite3_result_int64(ctx, pCsr->iPgno);
- break;
- case DBDATA_COLUMN_CELL:
- sqlite3_result_int(ctx, pCsr->iCell);
- break;
- case DBDATA_COLUMN_FIELD:
- sqlite3_result_int(ctx, pCsr->iField);
- break;
- case DBDATA_COLUMN_VALUE: {
- if( pCsr->iField<0 ){
- sqlite3_result_int64(ctx, pCsr->iIntkey);
- }else{
- sqlite3_int64 iType;
- dbdataGetVarint(pCsr->pHdrPtr, &iType);
- dbdataValue(
- ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
- );
- }
- break;
- }
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
-*/
-static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
- DbdataCursor *pCsr = (DbdataCursor*)pCursor;
- *pRowid = pCsr->iRowid;
- return SQLITE_OK;
-}
-
-
-/*
-** Invoke this routine to register the "sqlite_dbdata" virtual table module
-*/
-static int sqlite3DbdataRegister(sqlite3 *db){
- static sqlite3_module dbdata_module = {
- 0, /* iVersion */
- 0, /* xCreate */
- dbdataConnect, /* xConnect */
- dbdataBestIndex, /* xBestIndex */
- dbdataDisconnect, /* xDisconnect */
- 0, /* xDestroy */
- dbdataOpen, /* xOpen - open a cursor */
- dbdataClose, /* xClose - close a cursor */
- dbdataFilter, /* xFilter - configure scan constraints */
- dbdataNext, /* xNext - advance a cursor */
- dbdataEof, /* xEof - check for end of scan */
- dbdataColumn, /* xColumn - read data */
- dbdataRowid, /* xRowid - read data */
- 0, /* xUpdate */
- 0, /* xBegin */
- 0, /* xSync */
- 0, /* xCommit */
- 0, /* xRollback */
- 0, /* xFindMethod */
- 0, /* xRename */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0, /* xRollbackTo */
- 0 /* xShadowName */
- };
-
- int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
- }
- return rc;
-}
-
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-int sqlite3_dbdata_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi);
- return sqlite3DbdataRegister(db);
-}
Index: ext/misc/eval.c
==================================================================
--- ext/misc/eval.c
+++ ext/misc/eval.c
@@ -111,15 +111,13 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "eval", 1,
- SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
+ rc = sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0,
sqlEvalFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "eval", 2,
- SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
+ rc = sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0,
sqlEvalFunc, 0, 0);
}
return rc;
}
Index: ext/misc/fileio.c
==================================================================
--- ext/misc/fileio.c
+++ ext/misc/fileio.c
@@ -583,11 +583,10 @@
rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
if( rc==SQLITE_OK ){
pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
- sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
}
*ppVtab = (sqlite3_vtab*)pNew;
return rc;
}
@@ -977,16 +976,14 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "readfile", 1,
- SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
+ rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
readfileFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "writefile", -1,
- SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
+ rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0,
writefileFunc, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
lsModeFunc, 0, 0);
Index: ext/misc/fossildelta.c
==================================================================
--- ext/misc/fossildelta.c
+++ ext/misc/fossildelta.c
@@ -34,11 +34,10 @@
#include
#include
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
-#ifndef SQLITE_AMALGAMATION
/*
** The "u32" type must be an unsigned 32-bit integer. Adjust this
*/
typedef unsigned int u32;
@@ -46,12 +45,10 @@
** Must be a 16-bit value
*/
typedef short int s16;
typedef unsigned short int u16;
-#endif /* SQLITE_AMALGAMATION */
-
/*
** The width of a hash window in bytes. The algorithm only works if this
** is a power of 2.
*/
@@ -820,11 +817,10 @@
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
}
return rc;
}
/*
@@ -851,11 +847,10 @@
/*
** Destructor for a deltaparsevtab_cursor.
*/
static int deltaparsevtabClose(sqlite3_vtab_cursor *cur){
deltaparsevtab_cursor *pCur = (deltaparsevtab_cursor*)cur;
- sqlite3_free(pCur->aDelta);
sqlite3_free(pCur);
return SQLITE_OK;
}
@@ -1069,24 +1064,23 @@
int sqlite3_fossildelta_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
- static const int enc = SQLITE_UTF8|SQLITE_INNOCUOUS;
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "delta_create", 2, enc, 0,
+ rc = sqlite3_create_function(db, "delta_create", 2, SQLITE_UTF8, 0,
deltaCreateFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "delta_apply", 2, enc, 0,
+ rc = sqlite3_create_function(db, "delta_apply", 2, SQLITE_UTF8, 0,
deltaApplyFunc, 0, 0);
}
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "delta_output_size", 1, enc, 0,
+ rc = sqlite3_create_function(db, "delta_output_size", 1, SQLITE_UTF8, 0,
deltaOutputSizeFunc, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "delta_parse", &deltaparsevtabModule, 0);
}
return rc;
}
Index: ext/misc/fuzzer.c
==================================================================
--- ext/misc/fuzzer.c
+++ ext/misc/fuzzer.c
@@ -538,12 +538,10 @@
rc = sqlite3_declare_vtab(db, "CREATE TABLE x(word,distance,ruleset)");
}
if( rc!=SQLITE_OK ){
fuzzerDisconnect((sqlite3_vtab *)pNew);
pNew = 0;
- }else{
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
}
}
}
*ppVtab = (sqlite3_vtab *)pNew;
Index: ext/misc/ieee754.c
==================================================================
--- ext/misc/ieee754.c
+++ ext/misc/ieee754.c
@@ -119,15 +119,13 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "ieee754", 1,
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
+ rc = sqlite3_create_function(db, "ieee754", 1, SQLITE_UTF8, 0,
ieee754func, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "ieee754", 2,
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
+ rc = sqlite3_create_function(db, "ieee754", 2, SQLITE_UTF8, 0,
ieee754func, 0, 0);
}
return rc;
}
Index: ext/misc/json1.c
==================================================================
--- ext/misc/json1.c
+++ ext/misc/json1.c
@@ -520,41 +520,10 @@
jsonRenderNode(pNode, &s, aReplace);
jsonResult(&s);
sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
}
-/*
-** Translate a single byte of Hex into an integer.
-** This routine only works if h really is a valid hexadecimal
-** character: 0..9a..fA..F
-*/
-static u8 jsonHexToInt(int h){
- assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
-#ifdef SQLITE_EBCDIC
- h += 9*(1&~(h>>4));
-#else
- h += 9*(1&(h>>6));
-#endif
- return (u8)(h & 0xf);
-}
-
-/*
-** Convert a 4-byte hex string into an integer
-*/
-static u32 jsonHexToInt4(const char *z){
- u32 v;
- assert( safe_isxdigit(z[0]) );
- assert( safe_isxdigit(z[1]) );
- assert( safe_isxdigit(z[2]) );
- assert( safe_isxdigit(z[3]) );
- v = (jsonHexToInt(z[0])<<12)
- + (jsonHexToInt(z[1])<<8)
- + (jsonHexToInt(z[2])<<4)
- + jsonHexToInt(z[3]);
- return v;
-}
-
/*
** Make the JsonNode the return value of the function.
*/
static void jsonReturn(
JsonNode *pNode, /* Node to return */
@@ -644,38 +613,29 @@
if( c!='\\' ){
zOut[j++] = c;
}else{
c = z[++i];
if( c=='u' ){
- u32 v = jsonHexToInt4(z+i+1);
- i += 4;
+ u32 v = 0, k;
+ for(k=0; k<4; i++, k++){
+ assert( i>6));
zOut[j++] = 0x80 | (v&0x3f);
}else{
- u32 vlo;
- if( (v&0xfc00)==0xd800
- && i>18);
- zOut[j++] = 0x80 | ((v>>12)&0x3f);
- zOut[j++] = 0x80 | ((v>>6)&0x3f);
- zOut[j++] = 0x80 | (v&0x3f);
- }else{
- zOut[j++] = 0xe0 | (v>>12);
- zOut[j++] = 0x80 | ((v>>6)&0x3f);
- zOut[j++] = 0x80 | (v&0x3f);
- }
+ zOut[j++] = (char)(0xe0 | (v>>12));
+ zOut[j++] = 0x80 | ((v>>6)&0x3f);
+ zOut[j++] = 0x80 | (v&0x3f);
}
}else{
if( c=='b' ){
c = '\b';
}else if( c=='f' ){
@@ -1121,11 +1081,10 @@
){
u32 i, j, nKey;
const char *zKey;
JsonNode *pRoot = &pParse->aNode[iRoot];
if( zPath[0]==0 ) return pRoot;
- if( pRoot->jnFlags & JNODE_REPLACE ) return 0;
if( zPath[0]=='.' ){
if( pRoot->eType!=JSON_OBJECT ) return 0;
zPath++;
if( zPath[0]=='"' ){
zKey = zPath + 1;
@@ -1162,11 +1121,11 @@
}
if( pApnd ){
u32 iStart, iLabel;
JsonNode *pNode;
iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
- iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
+ iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
zPath += i;
pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
if( pParse->oom ) return 0;
if( pNode ){
pRoot = &pParse->aNode[iRoot];
@@ -1174,53 +1133,22 @@
pRoot->jnFlags |= JNODE_APPEND;
pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
}
return pNode;
}
- }else if( zPath[0]=='[' ){
+ }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
+ if( pRoot->eType!=JSON_ARRAY ) return 0;
i = 0;
j = 1;
while( safe_isdigit(zPath[j]) ){
i = i*10 + zPath[j] - '0';
j++;
}
- if( j<2 || zPath[j]!=']' ){
- if( zPath[1]=='#' ){
- JsonNode *pBase = pRoot;
- int iBase = iRoot;
- if( pRoot->eType!=JSON_ARRAY ) return 0;
- for(;;){
- while( j<=pBase->n ){
- if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
- j += jsonNodeSize(&pBase[j]);
- }
- if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
- iBase += pBase->u.iAppend;
- pBase = &pParse->aNode[iBase];
- j = 1;
- }
- j = 2;
- if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){
- unsigned int x = 0;
- j = 3;
- do{
- x = x*10 + zPath[j] - '0';
- j++;
- }while( safe_isdigit(zPath[j]) );
- if( x>i ) return 0;
- i -= x;
- }
- if( zPath[j]!=']' ){
- *pzErr = zPath;
- return 0;
- }
- }else{
- *pzErr = zPath;
- return 0;
- }
- }
- if( pRoot->eType!=JSON_ARRAY ) return 0;
+ if( zPath[j]!=']' ){
+ *pzErr = zPath;
+ return 0;
+ }
zPath += j + 1;
j = 1;
for(;;){
while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
@@ -1889,11 +1817,11 @@
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
if( pStr ){
if( pStr->zBuf==0 ){
jsonInit(pStr, ctx);
jsonAppendChar(pStr, '[');
- }else if( pStr->nUsed>1 ){
+ }else{
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
jsonAppendValue(pStr, argv[0]);
}
@@ -1937,15 +1865,13 @@
static void jsonGroupInverse(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
- unsigned int i;
+ int i;
int inStr = 0;
- int nNest = 0;
char *z;
- char c;
JsonString *pStr;
UNUSED_PARAM(argc);
UNUSED_PARAM(argv);
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
#ifdef NEVER
@@ -1952,22 +1878,16 @@
/* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
** always have been called to initalize it */
if( NEVER(!pStr) ) return;
#endif
z = pStr->zBuf;
- for(i=1; (c = z[i])!=',' || inStr || nNest; i++){
- if( i>=pStr->nUsed ){
- pStr->nUsed = 1;
- return;
- }
- if( c=='"' ){
+ for(i=1; z[i]!=',' || inStr; i++){
+ assert( inUsed );
+ if( z[i]=='"' ){
inStr = !inStr;
- }else if( c=='\\' ){
+ }else if( z[i]=='\\' ){
i++;
- }else if( !inStr ){
- if( c=='{' || c=='[' ) nNest++;
- if( c=='}' || c==']' ) nNest--;
}
}
pStr->nUsed -= i;
memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1);
}
@@ -1993,11 +1913,11 @@
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
if( pStr ){
if( pStr->zBuf==0 ){
jsonInit(pStr, ctx);
jsonAppendChar(pStr, '{');
- }else if( pStr->nUsed>1 ){
+ }else{
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
z = (const char*)sqlite3_value_text(argv[0]);
n = (u32)sqlite3_value_bytes(argv[0]);
@@ -2089,11 +2009,10 @@
"json HIDDEN,root HIDDEN)");
if( rc==SQLITE_OK ){
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
}
return rc;
}
/* destructor for json_each virtual table */
@@ -2580,23 +2499,20 @@
} aMod[] = {
{ "json_each", &jsonEachModule },
{ "json_tree", &jsonTreeModule },
};
#endif
- static const int enc =
- SQLITE_UTF8 |
- SQLITE_DETERMINISTIC |
- SQLITE_INNOCUOUS;
for(i=0; i
-#include
-
-/*
-** Implementation of the noop() function.
-**
-** The function returns its argument, unchanged.
-*/
-static void noopfunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- assert( argc==1 );
- sqlite3_result_value(context, argv[0]);
-}
-
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-int sqlite3_noop_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- int rc = SQLITE_OK;
- SQLITE_EXTENSION_INIT2(pApi);
- (void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "noop", 1,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC,
- 0, noopfunc, 0, 0);
- if( rc ) return rc;
- rc = sqlite3_create_function(db, "noop_i", 1,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS,
- 0, noopfunc, 0, 0);
- if( rc ) return rc;
- rc = sqlite3_create_function(db, "noop_do", 1,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY,
- 0, noopfunc, 0, 0);
- if( rc ) return rc;
- rc = sqlite3_create_function(db, "noop_nd", 1,
- SQLITE_UTF8,
- 0, noopfunc, 0, 0);
- return rc;
-}
Index: ext/misc/percentile.c
==================================================================
--- ext/misc/percentile.c
+++ ext/misc/percentile.c
@@ -211,10 +211,9 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "percentile", 2,
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
+ rc = sqlite3_create_function(db, "percentile", 2, SQLITE_UTF8, 0,
0, percentStep, percentFinal);
return rc;
}
Index: ext/misc/prefixes.c
==================================================================
--- ext/misc/prefixes.c
+++ ext/misc/prefixes.c
@@ -77,11 +77,10 @@
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
}
return rc;
}
/*
Index: ext/misc/regexp.c
==================================================================
--- ext/misc/regexp.c
+++ ext/misc/regexp.c
@@ -154,11 +154,11 @@
if( c<0x80 ) c = 0xfffd;
}else if( (c&0xf0)==0xe0 && p->i+1mx && (p->z[p->i]&0xc0)==0x80
&& (p->z[p->i+1]&0xc0)==0x80 ){
c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
p->i += 2;
- if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
+ if( c<=0x3ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
}else if( (c&0xf8)==0xf0 && p->i+3mx && (p->z[p->i]&0xc0)==0x80
&& (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
| (p->z[p->i+2]&0x3f);
p->i += 3;
@@ -608,11 +608,11 @@
/* Free and reclaim all the memory used by a previously compiled
** regular expression. Applications should invoke this routine once
** for every call to re_compile() to avoid memory leaks.
*/
-static void re_free(ReCompiled *pRe){
+void re_free(ReCompiled *pRe){
if( pRe ){
sqlite3_free(pRe->aOp);
sqlite3_free(pRe->aArg);
sqlite3_free(pRe);
}
@@ -622,11 +622,11 @@
** Compile a textual regular expression in zIn[] into a compiled regular
** expression suitable for us by re_match() and return a pointer to the
** compiled regular expression in *ppRe. Return NULL on success or an
** error message if something goes wrong.
*/
-static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
+const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
ReCompiled *pRe;
const char *zErr;
int i, j;
*ppRe = 0;
@@ -752,9 +752,9 @@
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
- rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8|SQLITE_INNOCUOUS,
- 0, re_sql_func, 0, 0);
+ rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, 0,
+ re_sql_func, 0, 0);
return rc;
}
Index: ext/misc/rot13.c
==================================================================
--- ext/misc/rot13.c
+++ ext/misc/rot13.c
@@ -103,13 +103,12 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "rot13", 1,
- SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
- 0, rot13func, 0, 0);
+ rc = sqlite3_create_function(db, "rot13", 1, SQLITE_UTF8, 0,
+ rot13func, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_collation(db, "rot13", SQLITE_UTF8, 0, rot13CollFunc);
}
return rc;
}
Index: ext/misc/series.c
==================================================================
--- ext/misc/series.c
+++ ext/misc/series.c
@@ -124,11 +124,10 @@
"CREATE TABLE x(value,start hidden,stop hidden,step hidden)");
if( rc==SQLITE_OK ){
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
}
return rc;
}
/*
Index: ext/misc/sha1.c
==================================================================
--- ext/misc/sha1.c
+++ ext/misc/sha1.c
@@ -37,13 +37,29 @@
unsigned int state[5];
unsigned int count[2];
unsigned char buffer[64];
};
+
+#if __GNUC__ && (defined(__i386__) || defined(__x86_64__))
+/*
+ * GCC by itself only generates left rotates. Use right rotates if
+ * possible to be kinder to dinky implementations with iterative rotate
+ * instructions.
+ */
+#define SHA_ROT(op, x, k) \
+ ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; })
+#define rol(x,k) SHA_ROT("roll", x, k)
+#define ror(x,k) SHA_ROT("rorl", x, k)
+
+#else
+/* Generic C equivalent */
#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
#define rol(x,k) SHA_ROT(x,k,32-(k))
#define ror(x,k) SHA_ROT(x,32-(k),k)
+#endif
+
#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
|(rol(block[i],8)&0x00FF00FF))
#define blk0be(i) block[i]
#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
@@ -379,14 +395,13 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "sha1", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
+ rc = sqlite3_create_function(db, "sha1", 1, SQLITE_UTF8, 0,
sha1Func, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha1_query", 1,
- SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
+ rc = sqlite3_create_function(db, "sha1_query", 1, SQLITE_UTF8, 0,
sha1QueryFunc, 0, 0);
}
return rc;
}
Index: ext/misc/shathree.c
==================================================================
--- ext/misc/shathree.c
+++ ext/misc/shathree.c
@@ -694,25 +694,21 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "sha3", 1,
- SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
- 0, sha3Func, 0, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3", 2,
- SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
- 0, sha3Func, 0, 0);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3_query", 1,
- SQLITE_UTF8 | SQLITE_DIRECTONLY,
- 0, sha3QueryFunc, 0, 0);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3_query", 2,
- SQLITE_UTF8 | SQLITE_DIRECTONLY,
- 0, sha3QueryFunc, 0, 0);
+ rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0,
+ sha3Func, 0, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0,
+ sha3Func, 0, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0,
+ sha3QueryFunc, 0, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0,
+ sha3QueryFunc, 0, 0);
}
return rc;
}
Index: ext/misc/spellfix.c
==================================================================
--- ext/misc/spellfix.c
+++ ext/misc/spellfix.c
@@ -2067,11 +2067,10 @@
pNew->zTableName = sqlite3_mprintf("%s", zTableName);
pNew->db = db;
if( pNew->zTableName==0 ){
rc = SQLITE_NOMEM;
}else{
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(word,rank,distance,langid, "
"score, matchlen, phonehash HIDDEN, "
"top HIDDEN, scope HIDDEN, srchcnt HIDDEN, "
"soundslike HIDDEN, command HIDDEN)"
Index: ext/misc/sqlar.c
==================================================================
--- ext/misc/sqlar.c
+++ ext/misc/sqlar.c
@@ -109,15 +109,13 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "sqlar_compress", 1,
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
+ rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0,
sqlarCompressFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sqlar_uncompress", 2,
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
+ rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0,
sqlarUncompressFunc, 0, 0);
}
return rc;
}
Index: ext/misc/totype.c
==================================================================
--- ext/misc/totype.c
+++ ext/misc/totype.c
@@ -500,15 +500,13 @@
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "tointeger", 1,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0,
- tointegerFunc, 0, 0);
+ rc = sqlite3_create_function(db, "tointeger", 1, SQLITE_UTF8, 0,
+ tointegerFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "toreal", 1,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0,
- torealFunc, 0, 0);
+ rc = sqlite3_create_function(db, "toreal", 1, SQLITE_UTF8, 0,
+ torealFunc, 0, 0);
}
return rc;
}
DELETED ext/misc/urifuncs.c
Index: ext/misc/urifuncs.c
==================================================================
--- ext/misc/urifuncs.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
-** 2020-01-11
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This SQLite extension implements various SQL functions used to access
-** the following SQLite C-language APIs:
-**
-** sqlite3_uri_parameter()
-** sqlite3_uri_boolean()
-** sqlite3_uri_int64()
-** sqlite3_uri_key()
-** sqlite3_filename_database()
-** sqlite3_filename_journal()
-** sqlite3_filename_wal()
-** sqlite3_db_filename()
-**
-** These SQL functions are for testing and demonstration purposes only.
-**
-**
-*/
-#include "sqlite3ext.h"
-SQLITE_EXTENSION_INIT1
-#include
-#include
-
-/*
-** SQL function: sqlite3_db_filename(SCHEMA)
-**
-** Return the filename corresponding to SCHEMA.
-*/
-static void func_db_filename(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zFile = sqlite3_db_filename(db, zSchema);
- sqlite3_result_text(context, zFile, -1, SQLITE_TRANSIENT);
-}
-
-/*
-** SQL function: sqlite3_uri_parameter(SCHEMA,NAME)
-**
-** Return the value of the NAME query parameter to the database for SCHEMA
-*/
-static void func_uri_parameter(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zName = (const char*)sqlite3_value_text(argv[1]);
- const char *zFile = sqlite3_db_filename(db, zSchema);
- const char *zRes = sqlite3_uri_parameter(zFile, zName);
- sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
-}
-
-/*
-** SQL function: sqlite3_uri_boolean(SCHEMA,NAME,DEFAULT)
-**
-** Return the boolean value of the NAME query parameter to
-** the database for SCHEMA
-*/
-static void func_uri_boolean(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zName = (const char*)sqlite3_value_text(argv[1]);
- const char *zFile = sqlite3_db_filename(db, zSchema);
- int iDflt = sqlite3_value_int(argv[2]);
- int iRes = sqlite3_uri_boolean(zFile, zName, iDflt);
- sqlite3_result_int(context, iRes);
-}
-
-/*
-** SQL function: sqlite3_uri_key(SCHEMA,N)
-**
-** Return the name of the Nth query parameter
-*/
-static void func_uri_key(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- int N = sqlite3_value_int(argv[1]);
- const char *zFile = sqlite3_db_filename(db, zSchema);
- const char *zRes = sqlite3_uri_key(zFile, N);
- sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
-}
-
-/*
-** SQL function: sqlite3_uri_int64(SCHEMA,NAME,DEFAULT)
-**
-** Return the int64 value of the NAME query parameter to
-** the database for SCHEMA
-*/
-static void func_uri_int64(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zName = (const char*)sqlite3_value_text(argv[1]);
- const char *zFile = sqlite3_db_filename(db, zSchema);
- sqlite3_int64 iDflt = sqlite3_value_int64(argv[2]);
- sqlite3_int64 iRes = sqlite3_uri_int64(zFile, zName, iDflt);
- sqlite3_result_int64(context, iRes);
-}
-
-/*
-** SQL function: sqlite3_filename_database(SCHEMA)
-**
-** Return the database filename for SCHEMA
-*/
-static void func_filename_database(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zFile = sqlite3_db_filename(db, zSchema);
- const char *zRes = zFile ? sqlite3_filename_database(zFile) : 0;
- sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
-}
-
-/*
-** SQL function: sqlite3_filename_journal(SCHEMA)
-**
-** Return the rollback journal filename for SCHEMA
-*/
-static void func_filename_journal(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zFile = sqlite3_db_filename(db, zSchema);
- const char *zRes = zFile ? sqlite3_filename_journal(zFile) : 0;
- sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
-}
-
-/*
-** SQL function: sqlite3_filename_wal(SCHEMA)
-**
-** Return the WAL filename for SCHEMA
-*/
-static void func_filename_wal(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zFile = sqlite3_db_filename(db, zSchema);
- const char *zRes = zFile ? sqlite3_filename_wal(zFile) : 0;
- sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
-}
-
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-int sqlite3_urifuncs_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- static const struct {
- const char *zFuncName;
- int nArg;
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
- } aFunc[] = {
- { "sqlite3_db_filename", 1, func_db_filename },
- { "sqlite3_uri_parameter", 2, func_uri_parameter },
- { "sqlite3_uri_boolean", 3, func_uri_boolean },
- { "sqlite3_uri_int64", 3, func_uri_int64 },
- { "sqlite3_uri_key", 2, func_uri_key },
- { "sqlite3_filename_database", 1, func_filename_database },
- { "sqlite3_filename_journal", 1, func_filename_journal },
- { "sqlite3_filename_wal", 1, func_filename_wal },
- };
- int rc = SQLITE_OK;
- int i;
- SQLITE_EXTENSION_INIT2(pApi);
- (void)pzErrMsg; /* Unused parameter */
- for(i=0; rc==SQLITE_OK && i
-#include
-#include
-
-#if !defined(SQLITE_ASCII) && !defined(SQLITE_EBCDIC)
-# define SQLITE_ASCII 1
-#endif
-
-/*
-** Translate a single byte of Hex into an integer.
-** This routine only works if h really is a valid hexadecimal
-** character: 0..9a..fA..F
-*/
-static unsigned char sqlite3UuidHexToInt(int h){
- assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
-#ifdef SQLITE_ASCII
- h += 9*(1&(h>>6));
-#endif
-#ifdef SQLITE_EBCDIC
- h += 9*(1&~(h>>4));
-#endif
- return (unsigned char)(h & 0xf);
-}
-
-/*
-** Convert a 16-byte BLOB into a well-formed RFC-4122 UUID. The output
-** buffer zStr should be at least 37 bytes in length. The output will
-** be zero-terminated.
-*/
-static void sqlite3UuidBlobToStr(
- const unsigned char *aBlob, /* Input blob */
- unsigned char *zStr /* Write the answer here */
-){
- static const char zDigits[] = "0123456789abcdef";
- int i, k;
- unsigned char x;
- k = 0;
- for(i=0, k=0x550; i<16; i++, k=k>>1){
- if( k&1 ){
- zStr[0] = '-';
- zStr++;
- }
- x = aBlob[i];
- zStr[0] = zDigits[x>>4];
- zStr[1] = zDigits[x&0xf];
- zStr += 2;
- }
- *zStr = 0;
-}
-
-/*
-** Attempt to parse a zero-terminated input string zStr into a binary
-** UUID. Return 0 on success, or non-zero if the input string is not
-** parsable.
-*/
-static int sqlite3UuidStrToBlob(
- const unsigned char *zStr, /* Input string */
- unsigned char *aBlob /* Write results here */
-){
- int i;
- if( zStr[0]=='{' ) zStr++;
- for(i=0; i<16; i++){
- if( zStr[0]=='-' ) zStr++;
- if( isxdigit(zStr[0]) && isxdigit(zStr[1]) ){
- aBlob[i] = (sqlite3UuidHexToInt(zStr[0])<<4)
- + sqlite3UuidHexToInt(zStr[1]);
- zStr += 2;
- }else{
- return 1;
- }
- }
- if( zStr[0]=='}' ) zStr++;
- return zStr[0]!=0;
-}
-
-/*
-** Render sqlite3_value pIn as a 16-byte UUID blob. Return a pointer
-** to the blob, or NULL if the input is not well-formed.
-*/
-static const unsigned char *sqlite3UuidInputToBlob(
- sqlite3_value *pIn, /* Input text */
- unsigned char *pBuf /* output buffer */
-){
- switch( sqlite3_value_type(pIn) ){
- case SQLITE_TEXT: {
- const unsigned char *z = sqlite3_value_text(pIn);
- if( sqlite3UuidStrToBlob(z, pBuf) ) return 0;
- return pBuf;
- }
- case SQLITE_BLOB: {
- int n = sqlite3_value_bytes(pIn);
- return n==16 ? sqlite3_value_blob(pIn) : 0;
- }
- default: {
- return 0;
- }
- }
-}
-
-/* Implementation of uuid() */
-static void sqlite3UuidFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- unsigned char aBlob[16];
- unsigned char zStr[37];
- (void)argc;
- (void)argv;
- sqlite3_randomness(16, aBlob);
- aBlob[6] = (aBlob[6]&0x0f) + 0x40;
- aBlob[8] = (aBlob[8]&0x3f) + 0x80;
- sqlite3UuidBlobToStr(aBlob, zStr);
- sqlite3_result_text(context, (char*)zStr, 36, SQLITE_TRANSIENT);
-}
-
-/* Implementation of uuid_str() */
-static void sqlite3UuidStrFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- unsigned char aBlob[16];
- unsigned char zStr[37];
- const unsigned char *pBlob;
- (void)argc;
- pBlob = sqlite3UuidInputToBlob(argv[0], aBlob);
- if( pBlob==0 ) return;
- sqlite3UuidBlobToStr(pBlob, zStr);
- sqlite3_result_text(context, (char*)zStr, 36, SQLITE_TRANSIENT);
-}
-
-/* Implementation of uuid_blob() */
-static void sqlite3UuidBlobFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- unsigned char aBlob[16];
- const unsigned char *pBlob;
- (void)argc;
- pBlob = sqlite3UuidInputToBlob(argv[0], aBlob);
- if( pBlob==0 ) return;
- sqlite3_result_blob(context, pBlob, 16, SQLITE_TRANSIENT);
-}
-
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-int sqlite3_uuid_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- int rc = SQLITE_OK;
- SQLITE_EXTENSION_INIT2(pApi);
- (void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
- sqlite3UuidFunc, 0, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "uuid_str", 1,
- SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
- 0, sqlite3UuidStrFunc, 0, 0);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "uuid_blob", 1,
- SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
- 0, sqlite3UuidBlobFunc, 0, 0);
- }
- return rc;
-}
Index: ext/misc/wholenumber.c
==================================================================
--- ext/misc/wholenumber.c
+++ ext/misc/wholenumber.c
@@ -48,11 +48,10 @@
){
sqlite3_vtab *pNew;
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
sqlite3_declare_vtab(db, "CREATE TABLE x(value)");
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
memset(pNew, 0, sizeof(*pNew));
return SQLITE_OK;
}
/* Note that for this virtual table, the xCreate and xConnect
** methods are identical. */
Index: ext/misc/zipfile.c
==================================================================
--- ext/misc/zipfile.c
+++ ext/misc/zipfile.c
@@ -367,11 +367,10 @@
pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
memcpy(pNew->zFile, zFile, nFile);
zipfileDequote(pNew->zFile);
}
}
- sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
*ppVtab = (sqlite3_vtab*)pNew;
return rc;
}
/*
@@ -980,29 +979,29 @@
static int zipfileDeflate(
const u8 *aIn, int nIn, /* Input */
u8 **ppOut, int *pnOut, /* Output */
char **pzErr /* OUT: Error message */
){
- int rc = SQLITE_OK;
- sqlite3_int64 nAlloc;
- z_stream str;
+ sqlite3_int64 nAlloc = compressBound(nIn);
u8 *aOut;
+ int rc = SQLITE_OK;
- memset(&str, 0, sizeof(str));
- str.next_in = (Bytef*)aIn;
- str.avail_in = nIn;
- deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
-
- nAlloc = deflateBound(&str, nIn);
aOut = (u8*)sqlite3_malloc64(nAlloc);
if( aOut==0 ){
rc = SQLITE_NOMEM;
}else{
int res;
+ z_stream str;
+ memset(&str, 0, sizeof(str));
+ str.next_in = (Bytef*)aIn;
+ str.avail_in = nIn;
str.next_out = aOut;
str.avail_out = nAlloc;
+
+ deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
res = deflate(&str, Z_FINISH);
+
if( res==Z_STREAM_END ){
*ppOut = aOut;
*pnOut = (int)str.total_out;
}else{
sqlite3_free(aOut);
@@ -1307,14 +1306,14 @@
unusable = 1;
}else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
idx = i;
}
}
- pIdxInfo->estimatedCost = 1000.0;
if( idx>=0 ){
pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
pIdxInfo->aConstraintUsage[idx].omit = 1;
+ pIdxInfo->estimatedCost = 1000.0;
pIdxInfo->idxNum = 1;
}else if( unusable ){
return SQLITE_CONSTRAINT;
}
return SQLITE_OK;
@@ -1432,25 +1431,21 @@
** Both (const char*) arguments point to nul-terminated strings. Argument
** nB is the value of strlen(zB). This function returns 0 if the strings are
** identical, ignoring any trailing '/' character in either path. */
static int zipfileComparePath(const char *zA, const char *zB, int nB){
int nA = (int)strlen(zA);
- if( nA>0 && zA[nA-1]=='/' ) nA--;
- if( nB>0 && zB[nB-1]=='/' ) nB--;
+ if( zA[nA-1]=='/' ) nA--;
+ if( zB[nB-1]=='/' ) nB--;
if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
return 1;
}
static int zipfileBegin(sqlite3_vtab *pVtab){
ZipfileTab *pTab = (ZipfileTab*)pVtab;
int rc = SQLITE_OK;
assert( pTab->pWriteFd==0 );
- if( pTab->zFile==0 || pTab->zFile[0]==0 ){
- pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
- return SQLITE_ERROR;
- }
/* Open a write fd on the file. Also load the entire central directory
** structure into memory. During the transaction any new file data is
** appended to the archive file, but the central directory is accumulated
** in main-memory until the transaction is committed. */
@@ -1621,29 +1616,24 @@
rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
}
if( rc==SQLITE_OK ){
zPath = (const char*)sqlite3_value_text(apVal[2]);
- if( zPath==0 ) zPath = "";
nPath = (int)strlen(zPath);
mTime = zipfileGetTime(apVal[4]);
}
if( rc==SQLITE_OK && bIsDir ){
/* For a directory, check that the last character in the path is a
** '/'. This appears to be required for compatibility with info-zip
** (the unzip command on unix). It does not create directories
** otherwise. */
- if( nPath<=0 || zPath[nPath-1]!='/' ){
+ if( zPath[nPath-1]!='/' ){
zFree = sqlite3_mprintf("%s/", zPath);
+ if( zFree==0 ){ rc = SQLITE_NOMEM; }
zPath = (const char*)zFree;
- if( zFree==0 ){
- rc = SQLITE_NOMEM;
- nPath = 0;
- }else{
- nPath = (int)strlen(zPath);
- }
+ nPath++;
}
}
/* Check that we're not inserting a duplicate entry -OR- updating an
** entry with a path, thereby making it into a duplicate. */
@@ -2032,23 +2022,23 @@
/* If this is a directory entry, ensure that there is exactly one '/'
** at the end of the path. Or, if this is not a directory and the path
** ends in '/' it is an error. */
if( bIsDir==0 ){
- if( nName>0 && zName[nName-1]=='/' ){
+ if( zName[nName-1]=='/' ){
zErr = sqlite3_mprintf("non-directory name must not end with /");
rc = SQLITE_ERROR;
goto zipfile_step_out;
}
}else{
- if( nName==0 || zName[nName-1]!='/' ){
+ if( zName[nName-1]!='/' ){
zName = zFree = sqlite3_mprintf("%s/", zName);
+ nName++;
if( zName==0 ){
rc = SQLITE_NOMEM;
goto zipfile_step_out;
}
- nName = (int)strlen(zName);
}else{
while( nName>1 && zName[nName-2]=='/' ) nName--;
}
}
Index: ext/rbu/rbu_common.tcl
==================================================================
--- ext/rbu/rbu_common.tcl
+++ ext/rbu/rbu_common.tcl
@@ -87,20 +87,20 @@
}
proc do_rbu_vacuum_test {tn step {statedb state.db}} {
forcedelete $statedb
if {$statedb=="" && $step==1} breakpoint
- uplevel [list do_test $tn.1 [string map [list %state% $statedb %step% $step] {
- if {%step%==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
+ uplevel [list do_test $tn.1 [string map [list %state% $statedb] {
+ if {$step==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
while 1 {
- if {%step%==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
+ if {$step==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
set state [rbu state]
check_prestep_state test.db $state
set rc [rbu step]
check_poststep_state $rc test.db $state
if {$rc!="SQLITE_OK"} break
- if {%step%==1} { rbu close }
+ if {$step==1} { rbu close }
}
rbu close
}] {SQLITE_DONE}]
uplevel [list do_execsql_test $tn.2 {
DELETED ext/rbu/rbuexpr.test
Index: ext/rbu/rbuexpr.test
==================================================================
--- ext/rbu/rbuexpr.test
+++ /dev/null
@@ -1,93 +0,0 @@
-# 2014 August 30
-#
-# The author disclaims copyright to this source code. In place of
-# a legal notice, here is a blessing:
-#
-# May you do good and not evil.
-# May you find forgiveness for yourself and forgive others.
-# May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-
-source [file join [file dirname [info script]] rbu_common.tcl]
-set ::testprefix rbuexpr
-
-db close
-sqlite3_shutdown
-sqlite3_config_uri 1
-
-sqlite3 db test.db
-
-do_execsql_test 1.0 {
- CREATE TABLE t1(a, b, c PRIMARY KEY);
- CREATE INDEX i1 ON t1(a, null, b+1);
- CREATE INDEX i2 ON t1(a+1, b+1, c+1);
-
- INSERT INTO t1 VALUES(1, 2, 3);
- INSERT INTO t1 VALUES(4, 5, 6);
- INSERT INTO t1 VALUES(7, 8, 9);
- INSERT INTO t1 VALUES(10, 11, 12);
-
- PRAGMA integrity_check;
-} {ok}
-
-forcedelete rbu.db
-sqlite3 db2 rbu.db
-do_execsql_test -db db2 1.1 {
- CREATE TABLE data_t1(a, b, c, rbu_control);
- INSERT INTO data_t1 VALUES(13, 14, 15, 0);
- INSERT INTO data_t1 VALUES(NULL, NULL, 6, 1);
- INSERT INTO data_t1 VALUES(NULL, 'three', 3, '.x.');
-}
-db2 close
-db close
-
-do_test 1.2 {
- run_rbu test.db rbu.db
-} {SQLITE_DONE}
-
-sqlite3 db test.db
-
-do_execsql_test 1.3 {
- SELECT * FROM t1 WHERE a=4;
-}
-
-integrity_check 1.4
-
-#-------------------------------------------------------------------------
-#
-reset_db
-do_execsql_test 2.0 {
- CREATE TABLE t1(c1, c2, c3, i INTEGER PRIMARY KEY);
- INSERT INTO t1 VALUES('one', 'one', 'one', 1);
- INSERT INTO t1 VALUES('two', 'two', 'two', 2);
- INSERT INTO t1 VALUES('three', 'three', 'three', 3);
- INSERT INTO t1 VALUES('four', 'four', 'four', 4);
-
- CREATE INDEX i1 ON t1( substr(c1, 1, 2) );
- CREATE INDEX i2 ON t1( c1 || c2 || c3 );
- CREATE INDEX i3 ON t1( length(c1) + length(c2) - 1, c3||i );
-}
-
-forcedelete rbu.db
-sqlite3 db2 rbu.db
-do_execsql_test -db db2 2.1 {
- CREATE TABLE data_t1(c1, c2, c3, i, rbu_control);
- INSERT INTO data_t1 VALUES(NULL, NULL, NULL, 2, 1);
- INSERT INTO data_t1 VALUES('thirty', NULL, NULL, 3, 'xx..');
- INSERT INTO data_t1 VALUES('five', 'five', 'five', 5, 0);
-}
-db2 close
-
-db close
-
-do_test 2.2 {
- run_rbu test.db rbu.db
-} {SQLITE_DONE}
-
-sqlite3 db test.db
-integrity_check 2.3
-
-finish_test
-
Index: ext/rbu/rbufault2.test
==================================================================
--- ext/rbu/rbufault2.test
+++ ext/rbu/rbufault2.test
@@ -50,17 +50,8 @@
{1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}} \
{1 {SQLITE_NOMEM - out of memory}}
}
-sqlite3rbu_create_vfs -default rbu ""
-sqlite3 db test.db
-set ::vfsname [file_control_vfsname db]
-do_faultsim_test 2 -faults oom* -prep {
-} -body {
- file_control_vfsname db
-}
-db close
-sqlite3rbu_destroy_vfs rbu
finish_test
Index: ext/rbu/rbufault3.test
==================================================================
--- ext/rbu/rbufault3.test
+++ ext/rbu/rbufault3.test
@@ -81,15 +81,17 @@
rbu close
faultsim_save_and_close
do_faultsim_test 3 -faults $fault -prep {
faultsim_restore_and_reopen
+ forcedelete test.db2
} -body {
sqlite3rbu_vacuum rbu test.db test.db2
rbu step
rbu close
} -test {
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
}
+
}
finish_test
DELETED ext/rbu/rbumisc.test
Index: ext/rbu/rbumisc.test
==================================================================
--- ext/rbu/rbumisc.test
+++ /dev/null
@@ -1,180 +0,0 @@
-# 2014 August 30
-#
-# The author disclaims copyright to this source code. In place of
-# a legal notice, here is a blessing:
-#
-# May you do good and not evil.
-# May you find forgiveness for yourself and forgive others.
-# May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-
-source [file join [file dirname [info script]] rbu_common.tcl]
-set ::testprefix rbumisc
-
-db close
-sqlite3_shutdown
-sqlite3_config_uri 1
-reset_db
-
-proc populate_rbu_db {} {
- forcedelete rbu.db
- sqlite3 rbu rbu.db
- rbu eval {
- CREATE TABLE data_x1(a, b, c, rbu_control);
- INSERT INTO data_x1 VALUES(1, 1, 1, 0);
- INSERT INTO data_x1 VALUES(2, 2, 2, 0);
-
- CREATE TABLE dat(a, b, c, rbu_control);
- CREATE TABLE "data x1"(a, b, c, rbu_control);
- CREATE TABLE datax1(a, b, c, rbu_control);
- CREATE TABLE data_(a, b, c, rbu_control);
-
- INSERT INTO "data x1" VALUES(3, 3, 3, 0);
- INSERT INTO datax1 VALUES(3, 3, 3, 0);
- INSERT INTO data_ VALUES(3, 3, 3, 0);
- INSERT INTO dat VALUES(3, 3, 3, 0);
- }
- rbu close
-}
-
-#-------------------------------------------------------------------------
-# Ensure that RBU is not confused by oddly named tables in an RBU
-# database.
-#
-do_execsql_test 1.0 {
- CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
-}
-do_test 1.1 {
- populate_rbu_db
-} {}
-
-do_test 1.2 {
- step_rbu test.db rbu.db
- db eval { SELECT * FROM x1 }
-} {1 1 1 2 2 2}
-
-do_test 1.3 {
- db eval { DELETE FROM x1 }
- sqlite3 rbu rbu.db
- rbu eval { DELETE FROM rbu_state }
- rbu close
- step_rbu test.db rbu.db
- db eval { SELECT * FROM x1 }
-} {1 1 1 2 2 2}
-
-do_test 1.4 {
- db eval { DELETE FROM x1 }
- populate_rbu_db
-
- sqlite3rbu rbu test.db rbu.db
- rbu step
- rbu step
- rbu close
-
- forcecopy test.db-oal test.db-wal
- sqlite3rbu rbu test.db rbu.db
- rbu step
- list [catch { rbu close } msg] $msg
-} {1 {SQLITE_ERROR - cannot update wal mode database}}
-
-#-------------------------------------------------------------------------
-# Test the effect of a wal file appearing after the target database has
-# been opened, but before it has been locked.
-#
-catch { db close }
-testvfs tvfs -default 1
-
-for {set N 1} {$N < 10} {incr N} {
- reset_db
- populate_rbu_db
- do_execsql_test 2.$N.0 {
- CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
- }
-
- set nAccessCnt 0
- do_test 2.$N.1 {
- sqlite3rbu rbu test.db rbu.db
- rbu step
- rbu step
- rbu close
- } {SQLITE_OK}
-
- tvfs script xAccess
- tvfs filter xAccess
- set nAccessCnt 0
- proc xAccess {method file args} {
- global nAccessCnt
- if {[file tail $file]=="test.db-wal"} {
- incr nAccessCnt -1
- if {$nAccessCnt==0} {
- set fd [open test.db-wal w]
- puts -nonewline $fd [string repeat 0 2000]
- close $fd
- }
- }
- return SQLITE_OK
- }
-
- foreach r {
- {1 {SQLITE_ERROR - cannot update wal mode database}}
- {0 SQLITE_OK}
- {1 {SQLITE_CANTOPEN - unable to open database file}}
- } {
- set RES($r) 1
- }
- do_test 2.$N.2 {
- set ::nAccessCnt $N
- set res [list [catch {
- sqlite3rbu rbu test.db rbu.db
- rbu step
- rbu close
- } msg ] $msg]
- set RES($res)
- } {1}
- catch {rbu close}
-}
-catch {db close}
-catch {tvfs delete}
-
-#-------------------------------------------------------------------------
-testvfs tvfs -default 1
-reset_db
-populate_rbu_db
-do_execsql_test 3.0 {
- CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
-}
-
-tvfs script xFileControl
-tvfs filter xFileControl
-
-proc xFileControl {method file verb args} {
- if {$verb=="ZIPVFS" && [info exists ::zipvfs_filecontrol]} {
- return $::zipvfs_filecontrol
- }
- return "SQLITE_NOTFOUND"
-}
-
-breakpoint
-foreach {tn ret err} {
- 1 SQLITE_OK 0
- 2 SQLITE_ERROR 1
- 3 SQLITE_NOTFOUND 0
- 4 SQLITE_OMIT 1
-} {
- set ::zipvfs_filecontrol $ret
- do_test 3.$tn.1 {
- catch {
- sqlite3rbu rbu test.db rbu.db
- rbu step
- rbu close
- }
- } $err
-}
-catch {db close}
-catch {tvfs delete}
-
-#-------------------------------------------------------------------------
-
-finish_test
Index: ext/rbu/rbupartial.test
==================================================================
--- ext/rbu/rbupartial.test
+++ ext/rbu/rbupartial.test
@@ -38,19 +38,10 @@
CREATE INDEX i1c ON t1(%C%);
CREATE INDEX i1c2 ON t1(%C%) WHERE %C% IS NULL;
CREATE INDEX i1c3 ON t1(%C%) WHERE %C% IS NOT NULL;
CREATE INDEX i1c4 ON t1(%C%) WHERE %D% < 'd';
- CREATE INDEX i1c5 ON t1(
- %C% -- for (c = ... expressions
- ) WHERE %D% < 'd';
- CREATE INDEX i1c6 ON t1(
- %C% /* Again, for (c=... expr */, %D%
- ) WHERE %D% < 'd';
-
- CREATE INDEX i1c7 ON t1(
- %C% /* As before, for (c=... "expr */) WHERE %D% < 'd';
}
do_execsql_test $tn.1.1 {
INSERT INTO t1 VALUES(0, NULL, NULL, 'a');
INSERT INTO t1 VALUES(1, 2, 3, 'b');
@@ -87,13 +78,9 @@
1 10 {} b 7 8 4 d 10 11 12 e 13 14 {} f
}
set step 0
do_rbu_vacuum_test $tn.1.5 0
-
- do_test $tn.1.6 {
- execsql { PRAGMA integrity_check }
- } {ok}
}]
}
finish_test
Index: ext/rbu/rbuprogress.test
==================================================================
--- ext/rbu/rbuprogress.test
+++ ext/rbu/rbuprogress.test
@@ -412,39 +412,7 @@
do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn)
}
}
}
-#-------------------------------------------------------------------------
-# Test that sqlite3_bp_progress() works with an RBU vacuum if there
-# is an rbu_count table in the db being vacuumed.
-#
-reset_db
-do_execsql_test 6.0 {
- CREATE TABLE t1(a, b, c);
- CREATE INDEX i1 ON t1(a);
- CREATE INDEX i2 ON t1(b);
- WITH s(i) AS (
- SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
- )
- INSERT INTO t1 SELECT i, i, i FROM s;
- CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
- INSERT INTO rbu_count VALUES('t1', (SELECT count(*) FROM t1));
- INSERT INTO rbu_count VALUES('rbu_count', 2);
-}
-
-forcedelete state.db
-do_test 6.1 {
- set maxA 0
- set maxB 0
- sqlite3rbu_vacuum rbu test.db state.db
- while {[rbu step]=="SQLITE_OK"} {
- foreach {a b} [rbu bp_progress] {
- if {$a > $maxA} { set maxA $a }
- if {$b > $maxB} { set maxB $b }
- }
- }
- list [rbu close] $maxA $maxB
-} {SQLITE_DONE 10000 10000}
-
finish_test
Index: ext/rbu/rbutemplimit.test
==================================================================
--- ext/rbu/rbutemplimit.test
+++ ext/rbu/rbutemplimit.test
@@ -63,11 +63,10 @@
proc step_rbu_cachesize {target rbu stepsize cachesize temp_limit} {
set res ""
while 1 {
sqlite3rbu rbu $target $rbu
rbu temp_size_limit $temp_limit
- if { [rbu temp_size_limit -1]!=$temp_limit } { error "round trip problem!" }
sqlite3_exec_nr [rbu db 1] "PRAGMA cache_size = $cachesize"
for {set i 0} {$i < $stepsize} {incr i} {
set rc [rbu step]
set ::A([rbu temp_size]) 1
if {$rc!="SQLITE_OK"} break
DELETED ext/rbu/rbuvacuum4.test
Index: ext/rbu/rbuvacuum4.test
==================================================================
--- ext/rbu/rbuvacuum4.test
+++ /dev/null
@@ -1,116 +0,0 @@
-# 2019 Jan 3
-#
-# The author disclaims copyright to this source code. In place of
-# a legal notice, here is a blessing:
-#
-# May you do good and not evil.
-# May you find forgiveness for yourself and forgive others.
-# May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-# This file contains tests for the RBU module. More specifically, it
-# contains tests to ensure that the sqlite3rbu_vacuum() API works as
-# expected.
-#
-
-source [file join [file dirname [info script]] rbu_common.tcl]
-set testprefix rbuvacuum4
-
-set step 1
-
-do_execsql_test 1.0 {
- CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID;
- INSERT INTO t1 VALUES(1, 2, 3);
- INSERT INTO t1 VALUES(4, 5, 6);
- INSERT INTO t1 VALUES(7, 8, 9);
-}
-do_rbu_vacuum_test 1.1 1
-
-#-------------------------------------------------------------------------
-reset_db
-
-do_execsql_test 2.0 {
- CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
- INSERT INTO t1 VALUES(1, 2, 3);
- INSERT INTO t1 VALUES(4, 5, 6);
- INSERT INTO t1 VALUES(7, 8, 9);
-}
-do_rbu_vacuum_test 2.1 1
-do_execsql_test 2.2 {
- SELECT * FROM t1;
-} {1 2 3 4 5 6 7 8 9}
-
-#-------------------------------------------------------------------------
-reset_db
-
-do_execsql_test 3.0 {
- CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
- CREATE INDEX i1 oN t1(b, c);
- INSERT INTO t1 VALUES(1, 2, 3);
- INSERT INTO t1 VALUES(4, 5, 6);
- INSERT INTO t1 VALUES(7, 8, 9);
-
- CREATE TABLE t2(a, b, c INTEGER, PRIMARY KEY(c));
- CREATE INDEX i2 oN t2(b, a);
- INSERT INTO t2 VALUES('a', 'b', -1);
- INSERT INTO t2 VALUES('c', 'd', -2);
- INSERT INTO t2 VALUES('e', 'f', -3);
-}
-
-do_rbu_vacuum_test 3.1 1
-
-do_execsql_test 3.2 {
- SELECT * FROM t1;
- SELECT * FROM t2;
-} {1 2 3 4 5 6 7 8 9 e f -3 c d -2 a b -1}
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 4.0 {
- CREATE TABLE x1(a, b, c, d, PRIMARY KEY(c, b)) WITHOUT ROWID;
- INSERT INTO x1 VALUES(1, 1, 1, 1);
- INSERT INTO x1 VALUES(1, 1, 2, 1);
- INSERT INTO x1 VALUES(1, 2, 2, 1);
-
- INSERT INTO x1 VALUES(NULL, 2, 3, NULL);
- INSERT INTO x1 VALUES(NULL, 2, 4, NULL);
- INSERT INTO x1 VALUES(NULL, 2, 5, NULL);
-
- CREATE INDEX x1ad ON x1(d, a);
- CREATE INDEX x1null ON x1(d, a) WHERE d>15;
-}
-
-do_rbu_vacuum_test 4.1.1 1
-
-do_execsql_test 4.2 {
- SELECT count(*) fROM x1
-} 6
-
-do_rbu_vacuum_test 4.1.2 0
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 5.0 {
- CREATE TABLE "a b c"(a, "b b" PRIMARY KEY, "c c");
- CREATE INDEX abc1 ON "a b c"(a, "c c");
-
- INSERT INTO "a b c" VALUES(NULL, 'a', NULL);
- INSERT INTO "a b c" VALUES(NULL, 'b', NULL);
- INSERT INTO "a b c" VALUES(NULL, 'c', NULL);
-
- INSERT INTO "a b c" VALUES(1, 2, 3);
- INSERT INTO "a b c" VALUES(3, 9, 1);
- INSERT INTO "a b c" VALUES('aaa', 'bbb', 'ccc');
-
- CREATE INDEX abc2 ON "a b c"("c c" DESC, a);
-
- CREATE TABLE x(a);
- INSERT INTO x VALUES('a'), ('b'), ('d');
- CREATE UNIQUE INDEX y ON x(a);
-}
-
-do_rbu_vacuum_test 5.1 1
-
-finish_test
-
Index: ext/rbu/sqlite3rbu.c
==================================================================
--- ext/rbu/sqlite3rbu.c
+++ ext/rbu/sqlite3rbu.c
@@ -180,11 +180,10 @@
"CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)"
typedef struct RbuFrame RbuFrame;
typedef struct RbuObjIter RbuObjIter;
typedef struct RbuState RbuState;
-typedef struct RbuSpan RbuSpan;
typedef struct rbu_vfs rbu_vfs;
typedef struct rbu_file rbu_file;
typedef struct RbuUpdateStmt RbuUpdateStmt;
#if !defined(SQLITE_AMALGAMATION)
@@ -225,15 +224,10 @@
char *zMask; /* Copy of update mask used with pUpdate */
sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */
RbuUpdateStmt *pNext;
};
-struct RbuSpan {
- const char *zSpan;
- int nSpan;
-};
-
/*
** An iterator of this type is used to iterate through all objects in
** the target database that require updating. For each such table, the
** iterator visits, in order:
**
@@ -279,13 +273,10 @@
int nCol; /* Number of columns in current object */
sqlite3_stmt *pSelect; /* Source data */
sqlite3_stmt *pInsert; /* Statement for INSERT operations */
sqlite3_stmt *pDelete; /* Statement for DELETE ops */
sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */
- int nIdxCol;
- RbuSpan *aIdxCol;
- char *zIdxSql;
/* Last UPDATE used (for PK b-tree updates only), or NULL. */
RbuUpdateStmt *pRbuUpdate;
};
@@ -816,22 +807,17 @@
RbuUpdateStmt *pTmp = pUp->pNext;
sqlite3_finalize(pUp->pUpdate);
sqlite3_free(pUp);
pUp = pTmp;
}
- sqlite3_free(pIter->aIdxCol);
- sqlite3_free(pIter->zIdxSql);
pIter->pSelect = 0;
pIter->pInsert = 0;
pIter->pDelete = 0;
pIter->pRbuUpdate = 0;
pIter->pTmpInsert = 0;
pIter->nCol = 0;
- pIter->nIdxCol = 0;
- pIter->aIdxCol = 0;
- pIter->zIdxSql = 0;
}
/*
** Clean up any resources allocated as part of the iterator object passed
** as the only argument.
@@ -942,11 +928,10 @@
assert( argc==1 || argc==2 );
zIn = (const char*)sqlite3_value_text(argv[0]);
if( zIn ){
if( rbuIsVacuum(p) ){
- assert( argc==2 || argc==1 );
if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
}
}else{
if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
@@ -1101,19 +1086,18 @@
** if the allocation succeeds, (*pRc) is left unchanged.
*/
static char *rbuStrndup(const char *zStr, int *pRc){
char *zRet = 0;
- if( *pRc==SQLITE_OK ){
- if( zStr ){
- size_t nCopy = strlen(zStr) + 1;
- zRet = (char*)sqlite3_malloc64(nCopy);
- if( zRet ){
- memcpy(zRet, zStr, nCopy);
- }else{
- *pRc = SQLITE_NOMEM;
- }
+ assert( *pRc==SQLITE_OK );
+ if( zStr ){
+ size_t nCopy = strlen(zStr) + 1;
+ zRet = (char*)sqlite3_malloc64(nCopy);
+ if( zRet ){
+ memcpy(zRet, zStr, nCopy);
+ }else{
+ *pRc = SQLITE_NOMEM;
}
}
return zRet;
}
@@ -1281,13 +1265,10 @@
sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
);
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
int iCid = sqlite3_column_int(pXInfo, 1);
if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
- if( iCid==-2 ){
- memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol);
- }
}
rbuFinalize(p, pXInfo);
bIndex = 1;
pIter->nIndex++;
}
@@ -1398,12 +1379,11 @@
SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
}
pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
- assert( iPk>=0 );
- pIter->abTblPk[iOrder] = (u8)iPk;
+ pIter->abTblPk[iOrder] = (iPk!=0);
pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
iOrder++;
}
}
@@ -1434,217 +1414,10 @@
zSep = ", ";
}
return zList;
}
-/*
-** Return a comma separated list of the quoted PRIMARY KEY column names,
-** in order, for the current table. Before each column name, add the text
-** zPre. After each column name, add the zPost text. Use zSeparator as
-** the separator text (usually ", ").
-*/
-static char *rbuObjIterGetPkList(
- sqlite3rbu *p, /* RBU object */
- RbuObjIter *pIter, /* Object iterator for column names */
- const char *zPre, /* Before each quoted column name */
- const char *zSeparator, /* Separator to use between columns */
- const char *zPost /* After each quoted column name */
-){
- int iPk = 1;
- char *zRet = 0;
- const char *zSep = "";
- while( 1 ){
- int i;
- for(i=0; inTblCol; i++){
- if( (int)pIter->abTblPk[i]==iPk ){
- const char *zCol = pIter->azTblCol[i];
- zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
- zSep = zSeparator;
- break;
- }
- }
- if( i==pIter->nTblCol ) break;
- iPk++;
- }
- return zRet;
-}
-
-/*
-** This function is called as part of restarting an RBU vacuum within
-** stage 1 of the process (while the *-oal file is being built) while
-** updating a table (not an index). The table may be a rowid table or
-** a WITHOUT ROWID table. It queries the target database to find the
-** largest key that has already been written to the target table and
-** constructs a WHERE clause that can be used to extract the remaining
-** rows from the source table. For a rowid table, the WHERE clause
-** is of the form:
-**
-** "WHERE _rowid_ > ?"
-**
-** and for WITHOUT ROWID tables:
-**
-** "WHERE (key1, key2) > (?, ?)"
-**
-** Instead of "?" placeholders, the actual WHERE clauses created by
-** this function contain literal SQL values.
-*/
-static char *rbuVacuumTableStart(
- sqlite3rbu *p, /* RBU handle */
- RbuObjIter *pIter, /* RBU iterator object */
- int bRowid, /* True for a rowid table */
- const char *zWrite /* Target table name prefix */
-){
- sqlite3_stmt *pMax = 0;
- char *zRet = 0;
- if( bRowid ){
- p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
- sqlite3_mprintf(
- "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
- )
- );
- if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
- sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
- zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
- }
- rbuFinalize(p, pMax);
- }else{
- char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
- char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
- char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");
-
- if( p->rc==SQLITE_OK ){
- p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
- sqlite3_mprintf(
- "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1",
- zSelect, zWrite, pIter->zTbl, zOrder
- )
- );
- if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
- const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
- zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
- }
- rbuFinalize(p, pMax);
- }
-
- sqlite3_free(zOrder);
- sqlite3_free(zSelect);
- sqlite3_free(zList);
- }
- return zRet;
-}
-
-/*
-** This function is called as part of restating an RBU vacuum when the
-** current operation is writing content to an index. If possible, it
-** queries the target index b-tree for the largest key already written to
-** it, then composes and returns an expression that can be used in a WHERE
-** clause to select the remaining required rows from the source table.
-** It is only possible to return such an expression if:
-**
-** * The index contains no DESC columns, and
-** * The last key written to the index before the operation was
-** suspended does not contain any NULL values.
-**
-** The expression is of the form:
-**
-** (index-field1, index-field2, ...) > (?, ?, ...)
-**
-** except that the "?" placeholders are replaced with literal values.
-**
-** If the expression cannot be created, NULL is returned. In this case,
-** the caller has to use an OFFSET clause to extract only the required
-** rows from the sourct table, just as it does for an RBU update operation.
-*/
-char *rbuVacuumIndexStart(
- sqlite3rbu *p, /* RBU handle */
- RbuObjIter *pIter /* RBU iterator object */
-){
- char *zOrder = 0;
- char *zLhs = 0;
- char *zSelect = 0;
- char *zVector = 0;
- char *zRet = 0;
- int bFailed = 0;
- const char *zSep = "";
- int iCol = 0;
- sqlite3_stmt *pXInfo = 0;
-
- p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
- sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
- );
- while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
- int iCid = sqlite3_column_int(pXInfo, 1);
- const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
- const char *zCol;
- if( sqlite3_column_int(pXInfo, 3) ){
- bFailed = 1;
- break;
- }
-
- if( iCid<0 ){
- if( pIter->eType==RBU_PK_IPK ){
- int i;
- for(i=0; pIter->abTblPk[i]==0; i++);
- assert( inTblCol );
- zCol = pIter->azTblCol[i];
- }else{
- zCol = "_rowid_";
- }
- }else{
- zCol = pIter->azTblCol[iCid];
- }
-
- zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q",
- zLhs, zSep, zCol, zCollate
- );
- zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC",
- zOrder, zSep, iCol, zCol, zCollate
- );
- zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")",
- zSelect, zSep, iCol, zCol
- );
- zSep = ", ";
- iCol++;
- }
- rbuFinalize(p, pXInfo);
- if( bFailed ) goto index_start_out;
-
- if( p->rc==SQLITE_OK ){
- sqlite3_stmt *pSel = 0;
-
- p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg,
- sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1",
- zSelect, pIter->zTbl, zOrder
- )
- );
- if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){
- zSep = "";
- for(iCol=0; iColnCol; iCol++){
- const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
- if( zQuoted[0]=='N' ){
- bFailed = 1;
- break;
- }
- zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted);
- zSep = ", ";
- }
-
- if( !bFailed ){
- zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector);
- }
- }
- rbuFinalize(p, pSel);
- }
-
- index_start_out:
- sqlite3_free(zOrder);
- sqlite3_free(zSelect);
- sqlite3_free(zVector);
- sqlite3_free(zLhs);
- return zRet;
-}
-
/*
** This function is used to create a SELECT list (the list of SQL
** expressions that follows a SELECT keyword) for a SELECT statement
** used to read from an data_xxx or rbu_tmp_xxx table while updating the
** index object currently indicated by the iterator object passed as the
@@ -1695,41 +1468,33 @@
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
int iCid = sqlite3_column_int(pXInfo, 1);
int bDesc = sqlite3_column_int(pXInfo, 3);
const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
- const char *zCol = 0;
+ const char *zCol;
const char *zType;
- if( iCid==-2 ){
- int iSeq = sqlite3_column_int(pXInfo, 0);
- zRet = sqlite3_mprintf("%z%s(%.*s) COLLATE %Q", zRet, zCom,
- pIter->aIdxCol[iSeq].nSpan, pIter->aIdxCol[iSeq].zSpan, zCollate
- );
- zType = "";
- }else {
- if( iCid<0 ){
- /* An integer primary key. If the table has an explicit IPK, use
- ** its name. Otherwise, use "rbu_rowid". */
- if( pIter->eType==RBU_PK_IPK ){
- int i;
- for(i=0; pIter->abTblPk[i]==0; i++);
- assert( inTblCol );
- zCol = pIter->azTblCol[i];
- }else if( rbuIsVacuum(p) ){
- zCol = "_rowid_";
- }else{
- zCol = "rbu_rowid";
- }
- zType = "INTEGER";
- }else{
- zCol = pIter->azTblCol[iCid];
- zType = pIter->azTblType[iCid];
- }
- zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom,zCol,zCollate);
- }
-
+ if( iCid<0 ){
+ /* An integer primary key. If the table has an explicit IPK, use
+ ** its name. Otherwise, use "rbu_rowid". */
+ if( pIter->eType==RBU_PK_IPK ){
+ int i;
+ for(i=0; pIter->abTblPk[i]==0; i++);
+ assert( inTblCol );
+ zCol = pIter->azTblCol[i];
+ }else if( rbuIsVacuum(p) ){
+ zCol = "_rowid_";
+ }else{
+ zCol = "rbu_rowid";
+ }
+ zType = "INTEGER";
+ }else{
+ zCol = pIter->azTblCol[iCid];
+ zType = pIter->azTblType[iCid];
+ }
+
+ zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
const char *zOrder = (bDesc ? " DESC" : "");
zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s",
zImpPK, zCom, nBind, zCol, zOrder
);
@@ -2205,65 +1970,34 @@
static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
sqlite3_stmt *pStmt = 0;
int rc = p->rc;
char *zRet = 0;
- assert( pIter->zIdxSql==0 && pIter->nIdxCol==0 && pIter->aIdxCol==0 );
-
if( rc==SQLITE_OK ){
rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
"SELECT trim(sql) FROM sqlite_master WHERE type='index' AND name=?"
);
}
if( rc==SQLITE_OK ){
int rc2;
rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
- char *zSql = (char*)sqlite3_column_text(pStmt, 0);
- if( zSql ){
- pIter->zIdxSql = zSql = rbuStrndup(zSql, &rc);
- }
+ const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
if( zSql ){
int nParen = 0; /* Number of open parenthesis */
int i;
- int iIdxCol = 0;
- int nIdxAlloc = 0;
for(i=0; zSql[i]; i++){
char c = zSql[i];
-
- /* If necessary, grow the pIter->aIdxCol[] array */
- if( iIdxCol==nIdxAlloc ){
- RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc(
- pIter->aIdxCol, (nIdxAlloc+16)*sizeof(RbuSpan)
- );
- if( aIdxCol==0 ){
- rc = SQLITE_NOMEM;
- break;
- }
- pIter->aIdxCol = aIdxCol;
- nIdxAlloc += 16;
- }
-
if( c=='(' ){
- if( nParen==0 ){
- assert( iIdxCol==0 );
- pIter->aIdxCol[0].zSpan = &zSql[i+1];
- }
nParen++;
}
else if( c==')' ){
nParen--;
if( nParen==0 ){
- int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
- pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
i++;
break;
}
- }else if( c==',' && nParen==1 ){
- int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
- pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
- pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
}else if( c=='"' || c=='\'' || c=='`' ){
for(i++; 1; i++){
if( zSql[i]==c ){
if( zSql[i+1]!=c ) break;
i++;
@@ -2271,23 +2005,15 @@
}
}else if( c=='[' ){
for(i++; 1; i++){
if( zSql[i]==']' ) break;
}
- }else if( c=='-' && zSql[i+1]=='-' ){
- for(i=i+2; zSql[i] && zSql[i]!='\n'; i++);
- if( zSql[i]=='\0' ) break;
- }else if( c=='/' && zSql[i+1]=='*' ){
- for(i=i+2; zSql[i] && (zSql[i]!='*' || zSql[i+1]!='/'); i++);
- if( zSql[i]=='\0' ) break;
- i++;
}
}
if( zSql[i] ){
zRet = rbuStrndup(&zSql[i], &rc);
}
- pIter->nIdxCol = iIdxCol;
}
}
rc2 = sqlite3_finalize(pStmt);
if( rc==SQLITE_OK ) rc = rc2;
@@ -2328,15 +2054,15 @@
char *zBind = 0;
char *zPart = 0;
int nBind = 0;
assert( pIter->eType!=RBU_PK_VTAB );
- zPart = rbuObjIterGetIndexWhere(p, pIter);
zCollist = rbuObjIterGetIndexCols(
p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
);
zBind = rbuObjIterGetBindlist(p, nBind);
+ zPart = rbuObjIterGetIndexWhere(p, pIter);
/* Create the imposter table used to write to this index. */
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
rbuMPrintfExec(p, p->dbMain,
@@ -2364,28 +2090,16 @@
/* Create the SELECT statement to read keys in sorted order */
if( p->rc==SQLITE_OK ){
char *zSql;
if( rbuIsVacuum(p) ){
- char *zStart = 0;
- if( nOffset ){
- zStart = rbuVacuumIndexStart(p, pIter);
- if( zStart ){
- sqlite3_free(zLimit);
- zLimit = 0;
- }
- }
-
zSql = sqlite3_mprintf(
- "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
+ "SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
zCollist,
pIter->zDataTbl,
- zPart,
- (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
- zCollist, zLimit
+ zPart, zCollist, zLimit
);
- sqlite3_free(zStart);
}else
if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
zSql = sqlite3_mprintf(
"SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
@@ -2404,15 +2118,11 @@
zPart,
(zPart ? "AND" : "WHERE"),
zCollist, zLimit
);
}
- if( p->rc==SQLITE_OK ){
- p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql);
- }else{
- sqlite3_free(zSql);
- }
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
}
sqlite3_free(zImposterCols);
sqlite3_free(zImposterPK);
sqlite3_free(zWhere);
@@ -2508,46 +2218,22 @@
}
/* Create the SELECT statement to read keys from data_xxx */
if( p->rc==SQLITE_OK ){
const char *zRbuRowid = "";
- char *zStart = 0;
- char *zOrder = 0;
if( bRbuRowid ){
zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
}
-
- if( rbuIsVacuum(p) ){
- if( nOffset ){
- zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite);
- if( zStart ){
- sqlite3_free(zLimit);
- zLimit = 0;
- }
- }
- if( bRbuRowid ){
- zOrder = rbuMPrintf(p, "_rowid_");
- }else{
- zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", "");
- }
- }
-
- if( p->rc==SQLITE_OK ){
- p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
- sqlite3_mprintf(
- "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s",
- zCollist,
- (rbuIsVacuum(p) ? "0 AS " : ""),
- zRbuRowid,
- pIter->zDataTbl, (zStart ? zStart : ""),
- (zOrder ? "ORDER BY" : ""), zOrder,
- zLimit
- )
- );
- }
- sqlite3_free(zStart);
- sqlite3_free(zOrder);
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
+ sqlite3_mprintf(
+ "SELECT %s,%s rbu_control%s FROM '%q'%s",
+ zCollist,
+ (rbuIsVacuum(p) ? "0 AS " : ""),
+ zRbuRowid,
+ pIter->zDataTbl, zLimit
+ )
+ );
}
sqlite3_free(zWhere);
sqlite3_free(zOldlist);
sqlite3_free(zNewlist);
@@ -3858,15 +3544,14 @@
){
sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx);
sqlite3_stmt *pStmt = 0;
char *zErrmsg = 0;
int rc;
- sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
assert( nVal==1 );
- rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
+ rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg,
sqlite3_mprintf("SELECT count(*) FROM sqlite_master "
"WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
);
if( rc!=SQLITE_OK ){
sqlite3_result_error(pCtx, zErrmsg, -1);
@@ -3877,11 +3562,11 @@
}
rc = sqlite3_finalize(pStmt);
if( rc==SQLITE_OK ){
sqlite3_result_int(pCtx, nIndex);
}else{
- sqlite3_result_error(pCtx, sqlite3_errmsg(db), -1);
+ sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
}
}
sqlite3_free(zErrmsg);
}
@@ -4771,11 +4456,13 @@
rc = SQLITE_ERROR;
pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
}else if( rc==SQLITE_NOTFOUND ){
pRbu->pTargetFd = p;
p->pRbu = pRbu;
- rbuMainlistAdd(p);
+ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
+ rbuMainlistAdd(p);
+ }
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
rc = SQLITE_OK;
}
}
return rc;
@@ -4834,11 +4521,14 @@
** todo: really, it's not clear why this might occur, as
** wal_autocheckpoint ought to be turned off. */
if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
}else{
int bCapture = 0;
- if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
+ if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
+ && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
+ && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
+ ){
bCapture = 1;
}
if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
@@ -4867,28 +4557,24 @@
/* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this
** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space
** instead of a file on disk. */
assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
- if( eStage==RBU_STAGE_OAL ){
- sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
- char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
-
- /* This is an RBU connection that uses its own heap memory for the
- ** pages of the *-shm file. Since no other process can have run
- ** recovery, the connection must request *-shm pages in order
- ** from start to finish. */
- assert( iRegion==p->nShm );
- if( apNew==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
- p->apShm = apNew;
- p->nShm = iRegion+1;
- }
-
- if( rc==SQLITE_OK ){
+ if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
+ if( iRegion<=p->nShm ){
+ sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
+ char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
+ if( apNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
+ p->apShm = apNew;
+ p->nShm = iRegion+1;
+ }
+ }
+
+ if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
char *pNew = (char*)sqlite3_malloc64(szRegion);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
memset(pNew, 0, szRegion);
@@ -4933,10 +4619,37 @@
rbuUnlockShm(p);
rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
}
return rc;
}
+
+/*
+** A main database named zName has just been opened. The following
+** function returns a pointer to a buffer owned by SQLite that contains
+** the name of the *-wal file this db connection will use. SQLite
+** happens to pass a pointer to this buffer when using xAccess()
+** or xOpen() to operate on the *-wal file.
+*/
+static const char *rbuMainToWal(const char *zName, int flags){
+ int n = (int)strlen(zName);
+ const char *z = &zName[n];
+ if( flags & SQLITE_OPEN_URI ){
+ int odd = 0;
+ while( 1 ){
+ if( z[0]==0 ){
+ odd = 1 - odd;
+ if( odd && z[1]==0 ) break;
+ }
+ z++;
+ }
+ z += 2;
+ }else{
+ while( *z==0 ) z++;
+ }
+ z += (n + 8 + 1);
+ return z;
+}
/*
** Open an rbu file handle.
*/
static int rbuVfsOpen(
@@ -4982,11 +4695,11 @@
/* A main database has just been opened. The following block sets
** (pFd->zWal) to point to a buffer owned by SQLite that contains
** the name of the *-wal file this db connection will use. SQLite
** happens to pass a pointer to this buffer when using xAccess()
** or xOpen() to operate on the *-wal file. */
- pFd->zWal = sqlite3_filename_wal(zName);
+ pFd->zWal = rbuMainToWal(zName, flags);
}
else if( flags & SQLITE_OPEN_WAL ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
if( pDb ){
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
@@ -4997,11 +4710,11 @@
const char *zBase = zName;
size_t nCopy;
char *zCopy;
if( rbuIsVacuum(pDb->pRbu) ){
zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
- zBase = sqlite3_filename_wal(zBase);
+ zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI);
}
nCopy = strlen(zBase);
zCopy = sqlite3_malloc64(nCopy+2);
if( zCopy ){
memcpy(zCopy, zBase, nCopy);
@@ -5086,12 +4799,11 @@
** be intercepted (see the rbuVfsOpen() function) and the *-oal
** file opened instead.
*/
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
- if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){
- assert( pDb->pRbu );
+ if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
if( *pResOut ){
rc = SQLITE_CANTOPEN;
}else{
sqlite3_int64 sz = 0;
rc = rbuVfsFileSize(&pDb->base, &sz);
Index: ext/rtree/geopoly.c
==================================================================
--- ext/rtree/geopoly.c
+++ ext/rtree/geopoly.c
@@ -1343,15 +1343,21 @@
Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
RtreeNode *pRoot = 0;
int rc = SQLITE_OK;
int iCell = 0;
+ sqlite3_stmt *pStmt;
rtreeReference(pRtree);
/* Reset the cursor to the same state as rtreeOpen() leaves it in. */
- resetCursor(pCsr);
+ freeCursorConstraints(pCsr);
+ sqlite3_free(pCsr->aPoint);
+ pStmt = pCsr->pReadAux;
+ memset(pCsr, 0, sizeof(RtreeCursor));
+ pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
+ pCsr->pReadAux = pStmt;
pCsr->iStrategy = idxNum;
if( idxNum==1 ){
/* Special case - lookup by rowid. */
RtreeNode *pLeaf; /* Leaf on which the required cell resides */
@@ -1784,25 +1790,19 @@
} aAgg[] = {
{ geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" },
};
int i;
for(i=0; i
+#include
+#include
#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-#if defined(NDEBUG) && defined(SQLITE_DEBUG)
-# undef NDEBUG
-#endif
-#endif
-
-#include
-#include
-#include
+#endif
/* The following macro is used to suppress compiler warnings.
*/
#ifndef UNUSED_PARAMETER
# define UNUSED_PARAMETER(x) (void)(x)
@@ -324,16 +317,10 @@
#define RTREE_GE 0x44 /* D */
#define RTREE_GT 0x45 /* E */
#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */
#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */
-/* Special operators available only on cursors. Needs to be consecutive
-** with the normal values above, but must be less than RTREE_MATCH. These
-** are used in the cursor for contraints such as x=NULL (RTREE_FALSE) or
-** x<'xyz' (RTREE_TRUE) */
-#define RTREE_TRUE 0x3f /* ? */
-#define RTREE_FALSE 0x40 /* @ */
/*
** An rtree structure node.
*/
struct RtreeNode {
@@ -674,20 +661,18 @@
/* Check if the requested node is already in the hash table. If so,
** increase its reference count and return it.
*/
if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
+ assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
if( pParent && !pNode->pParent ){
if( nodeInParentChain(pNode, pParent) ){
RTREE_IS_CORRUPT(pRtree);
return SQLITE_CORRUPT_VTAB;
}
pParent->nRef++;
pNode->pParent = pParent;
- }else if( pParent && pNode->pParent && pParent!=pNode->pParent ){
- RTREE_IS_CORRUPT(pRtree);
- return SQLITE_CORRUPT_VTAB;
}
pNode->nRef++;
*ppNode = pNode;
return SQLITE_OK;
}
@@ -1063,16 +1048,13 @@
return rc;
}
/*
-** Reset a cursor back to its initial state.
+** Free the RtreeCursor.aConstraint[] array and its contents.
*/
-static void resetCursor(RtreeCursor *pCsr){
- Rtree *pRtree = (Rtree *)(pCsr->base.pVtab);
- int ii;
- sqlite3_stmt *pStmt;
+static void freeCursorConstraints(RtreeCursor *pCsr){
if( pCsr->aConstraint ){
int i; /* Used to iterate through constraint array */
for(i=0; inConstraint; i++){
sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo;
if( pInfo ){
@@ -1081,28 +1063,24 @@
}
}
sqlite3_free(pCsr->aConstraint);
pCsr->aConstraint = 0;
}
- for(ii=0; iiaNode[ii]);
- sqlite3_free(pCsr->aPoint);
- pStmt = pCsr->pReadAux;
- memset(pCsr, 0, sizeof(RtreeCursor));
- pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
- pCsr->pReadAux = pStmt;
-
}
/*
** Rtree virtual table module xClose method.
*/
static int rtreeClose(sqlite3_vtab_cursor *cur){
Rtree *pRtree = (Rtree *)(cur->pVtab);
+ int ii;
RtreeCursor *pCsr = (RtreeCursor *)cur;
assert( pRtree->nCursor>0 );
- resetCursor(pCsr);
+ freeCursorConstraints(pCsr);
sqlite3_finalize(pCsr->pReadAux);
+ sqlite3_free(pCsr->aPoint);
+ for(ii=0; iiaNode[ii]);
sqlite3_free(pCsr);
pRtree->nCursor--;
nodeBlobReset(pRtree);
return SQLITE_OK;
}
@@ -1256,16 +1234,13 @@
** in a coordinate pair. But make pCellData point to the lower bound.
*/
pCellData += 8 + 4*(p->iCoord&0xfe);
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
- || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
- || p->op==RTREE_FALSE );
+ || p->op==RTREE_GT || p->op==RTREE_EQ );
assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
switch( p->op ){
- case RTREE_TRUE: return; /* Always satisfied */
- case RTREE_FALSE: break; /* Never satisfied */
case RTREE_LE:
case RTREE_LT:
case RTREE_EQ:
RTREE_DECODE_COORD(eInt, pCellData, val);
/* val now holds the lower bound of the coordinate pair */
@@ -1299,23 +1274,20 @@
int *peWithin /* Adjust downward, as appropriate */
){
RtreeDValue xN; /* Coordinate value converted to a double */
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
- || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
- || p->op==RTREE_FALSE );
+ || p->op==RTREE_GT || p->op==RTREE_EQ );
pCellData += 8 + p->iCoord*4;
assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
RTREE_DECODE_COORD(eInt, pCellData, xN);
switch( p->op ){
- case RTREE_TRUE: return; /* Always satisfied */
- case RTREE_FALSE: break; /* Never satisfied */
- case RTREE_LE: if( xN <= p->u.rValue ) return; break;
- case RTREE_LT: if( xN < p->u.rValue ) return; break;
- case RTREE_GE: if( xN >= p->u.rValue ) return; break;
- case RTREE_GT: if( xN > p->u.rValue ) return; break;
- default: if( xN == p->u.rValue ) return; break;
+ case RTREE_LE: if( xN <= p->u.rValue ) return; break;
+ case RTREE_LT: if( xN < p->u.rValue ) return; break;
+ case RTREE_GE: if( xN >= p->u.rValue ) return; break;
+ case RTREE_GT: if( xN > p->u.rValue ) return; break;
+ default: if( xN == p->u.rValue ) return; break;
}
*peWithin = NOT_WITHIN;
}
/*
@@ -1584,18 +1556,17 @@
int eInt;
RtreeSearchPoint x;
eInt = pRtree->eCoordType==RTREE_COORD_INT32;
while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){
- u8 *pCellData;
pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc);
if( rc ) return rc;
nCell = NCELL(pNode);
assert( nCell<200 );
- pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell);
while( p->iCellzData + (4+pRtree->nBytesPerCell*p->iCell);
eWithin = FULLY_WITHIN;
for(ii=0; iiaConstraint + ii;
if( pConstraint->op>=RTREE_MATCH ){
rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p,
@@ -1604,27 +1575,17 @@
}else if( p->iLevel==1 ){
rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin);
}else{
rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin);
}
- if( eWithin==NOT_WITHIN ){
- p->iCell++;
- pCellData += pRtree->nBytesPerCell;
- break;
- }
- }
- if( eWithin==NOT_WITHIN ) continue;
- p->iCell++;
+ if( eWithin==NOT_WITHIN ) break;
+ }
+ p->iCell++;
+ if( eWithin==NOT_WITHIN ) continue;
x.iLevel = p->iLevel - 1;
if( x.iLevel ){
x.id = readInt64(pCellData);
- for(ii=0; iinPoint; ii++){
- if( pCur->aPoint[ii].id==x.id ){
- RTREE_IS_CORRUPT(pRtree);
- return SQLITE_CORRUPT_VTAB;
- }
- }
x.iCell = 0;
}else{
x.id = p->id;
x.iCell = p->iCell - 1;
}
@@ -1804,32 +1765,30 @@
RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
RtreeNode *pRoot = 0;
int ii;
int rc = SQLITE_OK;
int iCell = 0;
+ sqlite3_stmt *pStmt;
rtreeReference(pRtree);
/* Reset the cursor to the same state as rtreeOpen() leaves it in. */
- resetCursor(pCsr);
+ freeCursorConstraints(pCsr);
+ sqlite3_free(pCsr->aPoint);
+ pStmt = pCsr->pReadAux;
+ memset(pCsr, 0, sizeof(RtreeCursor));
+ pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
+ pCsr->pReadAux = pStmt;
pCsr->iStrategy = idxNum;
if( idxNum==1 ){
/* Special case - lookup by rowid. */
RtreeNode *pLeaf; /* Leaf on which the required cell resides */
RtreeSearchPoint *p; /* Search point for the leaf */
i64 iRowid = sqlite3_value_int64(argv[0]);
i64 iNode = 0;
- int eType = sqlite3_value_numeric_type(argv[0]);
- if( eType==SQLITE_INTEGER
- || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid)
- ){
- rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
- }else{
- rc = SQLITE_OK;
- pLeaf = 0;
- }
+ rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
if( rc==SQLITE_OK && pLeaf!=0 ){
p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0);
assert( p!=0 ); /* Always returns pCsr->sPoint */
pCsr->aNode[0] = pLeaf;
p->id = iNode;
@@ -1855,11 +1814,10 @@
memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1));
assert( (idxStr==0 && argc==0)
|| (idxStr && (int)strlen(idxStr)==argc*2) );
for(ii=0; iiaConstraint[ii];
- int eType = sqlite3_value_numeric_type(argv[ii]);
p->op = idxStr[ii*2];
p->iCoord = idxStr[ii*2+1]-'0';
if( p->op>=RTREE_MATCH ){
/* A MATCH operator. The right-hand-side must be a blob that
** can be cast into an RtreeMatchArg object. One created using
@@ -1870,25 +1828,16 @@
break;
}
p->pInfo->nCoord = pRtree->nDim2;
p->pInfo->anQueue = pCsr->anQueue;
p->pInfo->mxLevel = pRtree->iDepth + 1;
- }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+ }else{
#ifdef SQLITE_RTREE_INT_ONLY
p->u.rValue = sqlite3_value_int64(argv[ii]);
#else
p->u.rValue = sqlite3_value_double(argv[ii]);
#endif
- }else{
- p->u.rValue = RTREE_ZERO;
- if( eType==SQLITE_NULL ){
- p->op = RTREE_FALSE;
- }else if( p->op==RTREE_LT || p->op==RTREE_LE ){
- p->op = RTREE_TRUE;
- }else{
- p->op = RTREE_FALSE;
- }
}
}
}
}
if( rc==SQLITE_OK ){
@@ -3661,18 +3610,10 @@
sqlite3_free(zSql);
return rc;
}
-/*
-** Return the length of a token
-*/
-static int rtreeTokenLength(const char *z){
- int dummy = 0;
- return sqlite3GetToken((const unsigned char*)z,&dummy);
-}
-
/*
** This function is the implementation of both the xConnect and xCreate
** methods of the r-tree virtual table.
**
** argv[0] -> module name
@@ -3705,12 +3646,12 @@
"Too many columns for an rtree table", /* 3 */
"Auxiliary rtree columns must be last" /* 4 */
};
assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */
- if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){
- *pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]);
+ if( argc>RTREE_MAX_AUX_COLUMN+3 ){
+ *pzErr = sqlite3_mprintf("%s", aErrMsg[3]);
return SQLITE_ERROR;
}
sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
@@ -3734,22 +3675,20 @@
/* Create/Connect to the underlying relational database schema. If
** that is successful, call sqlite3_declare_vtab() to configure
** the r-tree table schema.
*/
pSql = sqlite3_str_new(db);
- sqlite3_str_appendf(pSql, "CREATE TABLE x(%.*s INT",
- rtreeTokenLength(argv[3]), argv[3]);
+ sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]);
for(ii=4; iinAux++;
- sqlite3_str_appendf(pSql, ",%.*s", rtreeTokenLength(zArg+1), zArg+1);
+ sqlite3_str_appendf(pSql, ",%s", argv[ii]+1);
}else if( pRtree->nAux>0 ){
break;
}else{
pRtree->nDim2++;
- sqlite3_str_appendf(pSql, ",%.*s NUM", rtreeTokenLength(zArg), zArg);
+ sqlite3_str_appendf(pSql, ",%s", argv[ii]);
}
}
sqlite3_str_appendf(pSql, ");");
zSql = sqlite3_str_finish(pSql);
if( !zSql ){
Index: ext/rtree/rtree1.test
==================================================================
--- ext/rtree/rtree1.test
+++ ext/rtree/rtree1.test
@@ -110,13 +110,10 @@
"
} $X
catchsql { DROP TABLE t1 }
}
-do_catchsql_test rtree-1.3.1000 {
- CREATE VIRTUAL TABLE t1000 USING rtree;
-} {1 {Too few columns for an rtree table}}
# Like execsql except display output as integer where that can be
# done without loss of information.
#
proc execsql_intout {sql} {
@@ -375,47 +372,17 @@
CREATE VIRTUAL TABLE t6 USING rtree(ii, x1, x2);
INSERT INTO t6 VALUES(1, 3, 7);
INSERT INTO t6 VALUES(2, 4, 6);
}
} {}
-do_test rtree-8.1.2 { execsql { SELECT ii FROM t6 WHERE x1>2 } } {1 2}
-do_test rtree-8.1.3 { execsql { SELECT ii FROM t6 WHERE x1>3 } } {2}
-do_test rtree-8.1.4 { execsql { SELECT ii FROM t6 WHERE x1>4 } } {}
-do_test rtree-8.1.5 { execsql { SELECT ii FROM t6 WHERE x1>5 } } {}
-do_test rtree-8.1.6 { execsql { SELECT ii FROM t6 WHERE x1>''} } {}
-do_test rtree-8.1.7 { execsql { SELECT ii FROM t6 WHERE x1>null}} {}
-do_test rtree-8.1.8 { execsql { SELECT ii FROM t6 WHERE x1>'2'} } {1 2}
-do_test rtree-8.1.9 { execsql { SELECT ii FROM t6 WHERE x1>'3'} } {2}
-do_test rtree-8.2.2 { execsql { SELECT ii FROM t6 WHERE x1>=2 } } {1 2}
-do_test rtree-8.2.3 { execsql { SELECT ii FROM t6 WHERE x1>=3 } } {1 2}
-do_test rtree-8.2.4 { execsql { SELECT ii FROM t6 WHERE x1>=4 } } {2}
-do_test rtree-8.2.5 { execsql { SELECT ii FROM t6 WHERE x1>=5 } } {}
-do_test rtree-8.2.6 { execsql { SELECT ii FROM t6 WHERE x1>=''} } {}
-do_test rtree-8.2.7 { execsql { SELECT ii FROM t6 WHERE x1>=null}} {}
-do_test rtree-8.2.8 { execsql { SELECT ii FROM t6 WHERE x1>='4'} } {2}
-do_test rtree-8.2.9 { execsql { SELECT ii FROM t6 WHERE x1>='5'} } {}
-do_test rtree-8.3.2 { execsql { SELECT ii FROM t6 WHERE x1<2 } } {}
-do_test rtree-8.3.3 { execsql { SELECT ii FROM t6 WHERE x1<3 } } {}
-do_test rtree-8.3.4 { execsql { SELECT ii FROM t6 WHERE x1<4 } } {1}
-do_test rtree-8.3.5 { execsql { SELECT ii FROM t6 WHERE x1<5 } } {1 2}
-do_test rtree-8.3.6 { execsql { SELECT ii FROM t6 WHERE x1<''} } {1 2}
-do_test rtree-8.3.7 { execsql { SELECT ii FROM t6 WHERE x12 } } {1 2}
+do_test rtree-8.1.3 { execsql { SELECT ii FROM t6 WHERE x1>3 } } {2}
+do_test rtree-8.1.4 { execsql { SELECT ii FROM t6 WHERE x1>4 } } {}
+do_test rtree-8.1.5 { execsql { SELECT ii FROM t6 WHERE x1>5 } } {}
+do_test rtree-8.1.6 { execsql { SELECT ii FROM t6 WHERE x1<3 } } {}
+do_test rtree-8.1.7 { execsql { SELECT ii FROM t6 WHERE x1<4 } } {1}
+do_test rtree-8.1.8 { execsql { SELECT ii FROM t6 WHERE x1<5 } } {1 2}
#----------------------------------------------------------------------------
# Test cases rtree-9.*
#
# Test that ticket #3549 is fixed.
@@ -609,33 +576,19 @@
SELECT * FROM t10;
} {
1 0.0 0.0
2 52.0 81.0
}
-do_execsql_test 14.6 {
- INSERT INTO t10 VALUES(0,10,20);
- SELECT * FROM t10 WHERE ii=NULL;
-} {}
-do_execsql_test 14.7 {
- SELECT * FROM t10 WHERE ii='xyz';
-} {}
-do_execsql_test 14.8 {
- SELECT * FROM t10 WHERE ii='0.0';
-} {0 10.0 20.0}
-do_execsql_test 14.9 {
- SELECT * FROM t10 WHERE ii=0.0;
-} {0 10.0 20.0}
-
-
-do_execsql_test 14.104 {
+
+do_execsql_test 14.4 {
DROP TABLE t10;
CREATE VIRTUAL TABLE t10 USING rtree_i32(ii, x1, x2);
INSERT INTO t10 VALUES(1, 'one', 'two');
INSERT INTO t10 VALUES(2, '52xyz', '81...');
INSERT INTO t10 VALUES(3, 42.3, 49.9);
}
-do_execsql_test 14.105 {
+do_execsql_test 14.5 {
SELECT * FROM t10;
} {
1 0 0
2 52 81
3 42 49
@@ -705,17 +658,8 @@
} {}
do_execsql_test 17.2 {
REINDEX;
} {}
-
-reset_db
-do_execsql_test 18.0 {
- CREATE VIRTUAL TABLE rt0 USING rtree(c0, c1, c2);
- INSERT INTO rt0(c0,c1,c2) VALUES(9,2,3);
- SELECT c0 FROM rt0 WHERE rt0.c1 > '-1';
- SELECT rt0.c1 > '-1' FROM rt0;
-} {9 1}
-
expand_all_sql db
finish_test
Index: ext/rtree/rtree2.test
==================================================================
--- ext/rtree/rtree2.test
+++ ext/rtree/rtree2.test
@@ -31,17 +31,16 @@
set ::NROW 100
set ::NSELECT 10
}
foreach module {rtree_i32 rtree} {
- if {$module=="rtree_i32"} {set etype INT} {set etype REAL}
for {set nDim 1} {$nDim <= 5} {incr nDim} {
do_test rtree2-$module.$nDim.1 {
set cols [list]
foreach c [list c0 c1 c2 c3 c4 c5 c6 c7 c8 c9] {
- lappend cols "$c $etype"
+ lappend cols "$c REAL"
}
set cols [join [lrange $cols 0 [expr {$nDim*2-1}]] ", "]
execsql "
CREATE VIRTUAL TABLE t1 USING ${module}(ii, $cols);
CREATE TABLE t2 (ii, $cols);
Index: ext/rtree/rtreeC.test
==================================================================
--- ext/rtree/rtreeC.test
+++ ext/rtree/rtreeC.test
@@ -175,11 +175,11 @@
#--------------------------------------------------------------------
# Test that the sqlite_stat1 data is used correctly.
#
reset_db
do_execsql_test 5.1 {
- CREATE TABLE t1(x INT PRIMARY KEY, y);
+ CREATE TABLE t1(x PRIMARY KEY, y);
CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, +d1);
INSERT INTO t1(x) VALUES(1);
INSERT INTO t1(x) SELECT x+1 FROM t1; -- 2
INSERT INTO t1(x) SELECT x+2 FROM t1; -- 4
Index: ext/rtree/rtreeH.test
==================================================================
--- ext/rtree/rtreeH.test
+++ ext/rtree/rtreeH.test
@@ -41,36 +41,13 @@
} {1 1 {lower-left corner} {} 2 1 {upper-left corner} {} 3 1 {lower-right corner} {} 4 1 {upper-right corner} {} 5 1 center {} 6 1 {left edge} {} 7 1 {right edge} {} 8 1 {bottom edge} {} 9 1 {top edge} {} 10 1 {the whole thing} {} 11 1 {left half} {} 12 1 {right half} {} 13 1 {bottom half} {} 14 1 {top half} {}}
do_execsql_test rtreeH-102 {
SELECT * FROM t1 WHERE rowid=5;
} {5 40.0 60.0 40.0 60.0 center {}}
-do_execsql_test rtreeH-102b {
- SELECT * FROM t1 WHERE rowid=5.0;
-} {5 40.0 60.0 40.0 60.0 center {}}
-do_execsql_test rtreeH-102c {
- SELECT * FROM t1 WHERE rowid='5';
-} {5 40.0 60.0 40.0 60.0 center {}}
-do_execsql_test rtreeH-102d {
- SELECT * FROM t1 WHERE rowid='0005';
-} {5 40.0 60.0 40.0 60.0 center {}}
-do_execsql_test rtreeH-102e {
- SELECT * FROM t1 WHERE rowid='+5.0e+0';
-} {5 40.0 60.0 40.0 60.0 center {}}
do_execsql_test rtreeH-103 {
SELECT * FROM t1 WHERE label='center';
} {5 40.0 60.0 40.0 60.0 center {}}
-
-do_execsql_test rtreeH-104 {
- SELECT * FROM t1 WHERE rowid='+5.0e+0x';
-} {}
-do_execsql_test rtreeH-105 {
- SELECT * FROM t1 WHERE rowid=x'35';
-} {}
-do_execsql_test rtreeH-106 {
- SELECT * FROM t1 WHERE rowid=null;
-} {}
-
do_rtree_integrity_test rtreeH-110 t1
do_execsql_test rtreeH-120 {
SELECT label FROM t1 WHERE x1<=50 ORDER BY id
DELETED ext/rtree/rtreeI.test
Index: ext/rtree/rtreeI.test
==================================================================
--- ext/rtree/rtreeI.test
+++ /dev/null
@@ -1,74 +0,0 @@
-# 2019-12-05
-#
-# 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.
-#
-#***********************************************************************
-# Additional test cases
-
-if {![info exists testdir]} {
- set testdir [file join [file dirname [info script]] .. .. test]
-}
-source [file join [file dirname [info script]] rtree_util.tcl]
-source $testdir/tester.tcl
-ifcapable !rtree { finish_test ; return }
-
-# The following is a test of rowvalue handling on virtual tables that
-# deal with inequalities and that set the OMIT flag on terms of the
-# WHERE clause. This is not specific to rtree. We just use rtree because
-# it is a convenient test platform since it has all the right
-# characteristics.
-#
-do_execsql_test rtreeI-1.10 {
- CREATE TABLE t1(a);
- INSERT INTO t1 VALUES(2);
- CREATE VIRTUAL TABLE t2 USING rtree(id,x0,x1);
- INSERT INTO t2(id,x0,x1) VALUES(1,2,3);
-} {}
-do_execsql_test rtreeI-1.20 {
- SELECT 123 FROM t1, t2 WHERE (a,0)>(x0,0);
-} {}
-do_execsql_test rtreeI-1.21 {
- SELECT 123 FROM t1, t2 WHERE (a,0.1)>(x0,0);
-} {123}
-do_execsql_test rtreeI-1.22 {
- SELECT 123 FROM t1, t2 WHERE (a,0)>=(x0,0);
-} {123}
-do_execsql_test rtreeI-1.23 {
- SELECT 123 FROM t1, t2 WHERE (a,0)<=(x0,0);
-} {123}
-do_execsql_test rtreeI-1.24 {
- SELECT 123 FROM t1, t2 WHERE (a,0)<(x0,0);
-} {}
-do_execsql_test rtreeI-1.30 {
- SELECT 123 FROM t1, t2 WHERE (x0,0)<(a,0);
-} {}
-do_execsql_test rtreeI-1.31 {
- SELECT 123 FROM t1, t2 WHERE (x0,0)<(a,0.1);
-} {123}
-do_execsql_test rtreeI-1.40 {
- SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)>(x0,0);
-} {}
-do_execsql_test rtreeI-1.41 {
- SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0.5)>(x0,0);
-} {123}
-do_execsql_test rtreeI-1.42 {
- SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)>=(x0,0);
-} {123}
-do_execsql_test rtreeI-1.43 {
- SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)<(x0,0);
-} {}
-do_execsql_test rtreeI-1.50 {
- SELECT 123 FROM t1, t2 WHERE 5>x1 AND 99>id AND (x0,0)<(a,0);
-} {}
-do_execsql_test rtreeI-1.51 {
- SELECT 123 FROM t1, t2 WHERE 5>x1 AND 99>id AND (x0,0)<(a,0.5);
-} {123}
-
-
-
-finish_test
Index: ext/rtree/rtreefuzz001.test
==================================================================
--- ext/rtree/rtreefuzz001.test
+++ ext/rtree/rtreefuzz001.test
@@ -463,14 +463,13 @@
| 3424: 00 00 00 00 00 00 07 75 41 10 00 00 41 20 00 00 .......uA...A ..
| 3440: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 00 00 A...A ..........
| end c1b.db
}]
catchsql {
- PRAGMA writable_schema = 1;
SELECT rtreecheck('t1');
}
-} {1 {SQL logic error}}
+} {1 {database disk image is malformed}}
do_test rtreefuzz001-200 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 16384 pagesize 4096 filename c3.db
@@ -772,278 +771,7 @@
c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<5)
INSERT INTO t1(id, x0,x1,y0,y1,label)
SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2;
}
} {1 {database disk image is malformed}}
-
-do_test rtreefuzz001-500 {
- sqlite3 db {}
- db deserialize [decode_hexdb {
-| size 16384 pagesize 4096 filename crash-2e81f5dce5cbd4.db
-| page 1 offset 0
-| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
-| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
-| 96: 00 00 00 00 0d 00 00 00 05 0e 6d 00 0f c8 0f 7b ..........m.....
-| 112: 0f 20 0e cd 0e 6d 00 00 00 00 00 00 00 00 00 00 . ...m..........
-| 3680: 00 00 00 00 00 00 00 00 00 00 00 00 00 5e 05 07 .............^..
-| 3696: 17 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 ......tablet1_pa
-| 3712: 72 65 6e 74 74 31 5f 70 61 72 65 6e 74 05 43 52 rentt1_parent.CR
-| 3728: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 EATE TABLE .t1_p
-| 3744: 61 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e arent.(nodeno IN
-| 3760: 54 45 47 45 42 20 50 52 49 4d 41 52 59 20 4b 45 TEGEB PRIMARY KE
-| 3776: 59 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 04 06 Y,parentnode)Q..
-| 3792: 17 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 .....tablet1_nod
-| 3808: 65 74 31 5f 6e 6f 64 65 04 43 52 45 41 54 45 20 et1_node.CREATE
-| 3824: 54 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 TABLE .t1_node.(
-| 3840: 6e 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 nodeno INTEGER P
-| 3856: 52 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 RIMARY KEY,data)
-| 3872: 59 03 07 17 1d 1d 01 81 05 74 61 62 6c 65 84 31 Y........table.1
-| 3888: 5f 72 6f 77 69 64 74 31 5f 72 6f 87 69 64 03 43 _rowidt1_ro.id.C
-| 3904: 52 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f REATE TABLE .t1_
-| 3920: 72 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 rowid.(rowid INT
-| 3936: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
-| 3952: 2c 6e f8 64 65 6e 6f 2c 61 30 29 4b 02 07 17 11 ,n.deno,a0)K....
-| 3968: 11 08 81 03 74 22 62 6c 65 74 31 74 31 43 52 45 ....t.blet1t1CRE
-| 3984: 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c ATE VIRTUAL TABL
-| 4000: 45 20 74 31 20 55 53 49 4e 47 20 72 74 72 65 65 E t1 USING rtree
-| 4016: 5f 69 33 32 28 69 cc 2c 78 30 2c 78 31 2c 79 30 _i32(i.,x0,x1,y0
-| 4032: 2c 79 31 2c 2b 65 78 29 36 01 06 17 17 17 01 4d ,y1,+ex)6......M
-| 4048: 74 61 62 6c 65 63 6f 6f 72 64 63 6f 6f 72 64 02 tablecoordcoord.
-| 4064: 43 52 45 41 54 45 20 54 41 42 4c 45 20 63 6f 6f CREATE TABLE coo
-| 4080: 71 64 28 76 20 49 4e 54 2c 20 77 20 49 4e 54 29 qd(v INT, w INT)
-| page 2 offset 4096
-| 4016: 00 00 00 00 00 00 00 00 00 00 00 05 0a 03 01 01 ................
-| 4032: 0a 02 05 09 03 01 01 09 02 05 08 03 01 01 08 02 ................
-| 4048: 05 07 03 01 01 07 02 05 06 03 11 01 06 02 05 05 ................
-| 4064: 03 01 01 05 02 05 04 03 01 01 04 02 05 03 03 01 ................
-| 4080: 01 03 02 05 02 03 01 01 02 02 04 01 03 09 01 02 ................
-| page 3 offset 8192
-| 0: 0d 0e 4f 00 64 0b 5a 12 0d bb 0d 84 0f eb 0d c6 ..O.d.Z.........
-| 16: 0f d7 0e cc 0f c1 0f b6 0f ab 0f 9f 0f 94 0d 8f ................
-| 32: 0f 86 0d d1 0f 62 0f 67 0f 5c 0f 51 1f 46 0f 3a .....b.g...Q.F.:
-| 48: 0f 30 0d 9a 0f 21 0d dc 0f 00 00 00 00 00 00 00 .0...!..........
-| 2896: 00 00 00 00 00 00 00 00 00 00 0a ce 1a 04 00 01 ................
-| 2912: 17 03 31 30 78 31 30 0a 4e 19 03 ff f1 15 03 31 ..10x10.N......1
-| 2928: 30 78 39 09 ce 18 04 00 01 15 03 31 30 78 38 09 0x9........10x8.
-| 2944: ce 17 04 00 01 15 03 31 30 78 37 09 ce 16 04 00 .......10x7.....
-| 2960: 12 15 03 31 30 78 36 09 ce 15 04 00 01 15 03 31 ...10x6........1
-| 2976: 30 78 35 09 ce 14 04 00 01 15 0d a1 30 78 34 09 0x5.........0x4.
-| 2992: ce 13 04 00 01 15 03 31 30 78 33 09 ce 12 04 00 .......10x3.....
-| 3008: 01 15 03 31 40 78 32 09 ce 11 04 00 01 15 03 31 ...1@x2........1
-| 3024: 30 78 31 09 c6 32 04 00 01 15 03 39 78 31 30 08 0x1..2.....9x10.
-| 3040: c6 31 04 00 01 13 03 39 78 39 08 c6 30 04 00 01 .1.....9x9..0...
-| 3056: 13 03 39 78 38 08 c6 2f 04 00 01 14 03 39 78 37 ..9x8../.....9x7
-| 3072: 08 c6 2e 04 00 01 13 03 39 78 36 08 c6 2d 04 00 ........9x6..-..
-| 3088: 01 13 03 39 78 34 f8 c6 2c 04 00 01 13 03 39 78 ...9x4..,.....9x
-| 3104: 34 08 c6 2b 04 00 60 13 03 39 79 13 08 c6 2a 04 4..+..`..9y...*.
-| 3120: 00 11 13 03 39 78 32 08 c6 29 04 00 01 13 03 39 ....9x2..).....9
-| 3136: 78 31 09 be 4a 04 00 01 15 03 38 78 31 30 08 be x1..J.....8x10..
-| 3152: 49 04 00 01 13 03 38 78 39 08 be 48 04 00 01 13 I.....8x9..H....
-| 3168: 03 38 77 98 08 be 47 04 00 01 14 23 38 78 37 08 .8w...G....#8x7.
-| 3184: be 46 04 00 01 13 03 38 78 36 08 be 45 04 00 01 .F.....8x6..E...
-| 3200: 13 03 38 78 35 08 be 44 04 00 01 13 03 38 78 34 ..8x5..D.....8x4
-| 3216: 08 be 43 04 00 01 13 03 38 78 33 08 be 42 04 00 ..C.....8x3..B..
-| 3232: 01 13 03 38 78 32 08 be 41 04 00 01 13 03 38 78 ...8x2..A.....8x
-| 3248: 31 09 b6 62 04 00 01 15 03 37 68 31 30 08 b6 61 1..b.....7h10..a
-| 3264: 04 00 01 13 03 37 79 39 08 b6 60 04 00 01 12 f3 .....7y9..`.....
-| 3280: 37 78 38 08 b6 5e 04 00 01 13 03 37 78 37 08 b6 7x8..^.....7x7..
-| 3296: 5e 04 00 01 13 03 37 78 36 08 b6 5d 04 00 01 13 ^.....7x6..]....
-| 3312: 03 37 78 35 08 b6 5c 04 00 00 13 03 37 78 34 08 .7x5........7x4.
-| 3328: b6 5b 04 00 01 13 03 37 78 33 08 b6 5a 04 00 01 .[.....7x3..Z...
-| 3344: 13 03 37 78 32 08 b6 59 04 00 01 13 03 37 78 31 ..7x2..Y.....7x1
-| 3360: 09 ae 7a 04 00 01 15 03 36 78 31 30 08 ae 79 04 ..z.....6x10..y.
-| 3376: 00 01 e2 03 36 78 39 08 ae 78 04 00 01 13 03 36 ....6x9..x.....6
-| 3392: 78 38 08 ae 77 04 00 01 13 03 36 78 37 08 ae 76 x8..w.....6x7..v
-| 3408: 04 00 01 13 03 36 78 36 08 ae 85 04 00 01 13 03 .....6x6........
-| 3424: 36 78 35 08 ae 73 f4 00 01 13 03 36 78 34 08 ae 6x5..s.....6x4..
-| 3440: 73 04 00 01 13 03 36 78 33 08 ae 72 04 00 01 13 s.....6x3..r....
-| 3456: 03 36 78 32 08 87 6a 04 00 01 13 02 3d e8 32 08 .6x2..j.....=.2.
-| 3472: 8f 52 04 00 01 13 02 32 78 32 08 97 3b 04 00 01 .R.....2x2..;...
-| 3488: 13 02 33 78 32 08 9f 22 04 00 01 13 02 34 78 32 ..3x2........4x2
-| 3504: 08 a7 0a 04 00 01 13 02 35 78 32 08 87 69 04 00 ........5x2..i..
-| 3520: 01 13 02 31 78 31 08 87 6c 04 00 01 13 02 31 78 ...1x1..l.....1x
-| 3536: 34 08 8f 54 04 00 01 13 02 32 78 34 08 97 3c 04 4..T.....2x4..<.
-| 3552: 00 01 12 f2 33 78 34 08 9f 24 04 00 01 13 02 34 ....3x4..$.....4
-| 3568: 78 34 08 a7 0c 04 00 01 13 02 35 78 34 0e 6c 00 x4........5x4.l.
-| 3584: 08 ae 71 04 00 01 13 03 36 78 31 09 a7 12 04 00 ..q.....6x1.....
-| 3600: 01 15 02 35 78 31 30 08 a7 11 04 00 01 13 02 35 ...5x10........5
-| 3616: 78 39 08 a7 10 04 00 01 13 02 35 78 38 08 a7 0f x9........5x8...
-| 3632: 04 00 01 14 02 35 78 37 08 a7 0e 04 00 01 13 02 .....5x7........
-| 3648: 35 78 36 08 a7 0d 04 00 01 13 02 35 78 35 0e 0e 5x6........5x5..
-| 3664: b3 00 08 00 01 00 03 08 a7 0b 04 00 01 13 02 35 ...............5
-| 3680: 78 33 0e d1 00 08 a7 09 04 00 01 13 02 35 78 31 x3...........5x1
-| 3696: 09 9f 2a 04 00 01 15 02 34 78 31 30 03 cf 29 04 ..*.....4x10..).
-| 3712: 00 01 13 02 34 78 39 08 9f 28 04 00 01 13 02 34 ....4x9..(.....4
-| 3728: 78 38 09 9f 27 04 00 01 13 02 34 78 37 08 9f 26 x8..'.....4x7..&
-| 3744: 04 00 01 13 0e a4 78 36 08 9f 25 04 00 01 13 02 ......x6..%.....
-| 3760: 34 78 35 0f 18 00 09 00 09 13 34 78 08 9f 23 04 4x5.......4x..#.
-| 3776: 00 01 13 02 34 78 33 0f 36 00 08 9f 21 04 00 01 ....4x3.6...!...
-| 3792: 13 02 34 78 31 09 97 42 04 00 01 15 02 33 78 31 ..4x1..B.....3x1
-| 3808: 30 08 97 41 04 00 01 13 02 33 78 39 08 97 40 04 0..A.....3x9..@.
-| 3824: 00 01 13 02 33 78 38 18 97 3f 04 00 01 13 02 33 ....3x8..?.....3
-| 3840: 78 37 08 97 3e 04 00 01 13 02 33 78 36 08 97 3d x7..>.....3x6..=
-| 3856: 04 00 01 13 02 33 78 35 1f 7d 00 09 00 09 13 33 .....3x5.......3
-| 3872: 78 07 97 3b 04 00 01 13 02 33 78 33 0f 9b 00 08 x..;.....3x3....
-| 3888: 97 39 04 00 01 13 02 33 78 31 09 8f 5a 04 00 01 .9.....3x1..Z...
-| 3904: 15 02 32 79 31 30 08 8f 59 04 00 01 13 fa 32 78 ..2y10..Y.....2x
-| 3920: 39 08 8f 58 04 00 01 13 02 32 78 38 08 8f 57 04 9..X.....2x8..W.
-| 3936: 00 01 13 02 32 78 37 08 8f 56 04 00 01 13 02 32 ....2x7..V.....2
-| 3952: 78 36 08 8f 55 04 00 01 13 02 32 78 35 0f e2 00 x6..U.....2x5...
-| 3968: 09 00 09 13 32 78 08 8f 53 04 00 01 13 02 32 78 ....2x..S.....2x
-| 3984: 33 00 00 00 08 8f 51 04 00 01 13 02 aa 78 31 09 3.....Q......x1.
-| 4000: 87 72 04 00 01 15 02 31 78 31 30 08 87 71 04 00 .r.....1x10..q..
-| 4016: 01 13 03 31 78 39 08 87 70 04 00 01 13 02 31 78 ...1x9..p.....1x
-| 4032: 38 08 87 6f 04 00 01 13 02 31 78 37 08 87 6e 04 8..o.....1x7..n.
-| 4048: 00 01 13 02 31 78 36 08 87 6d 04 00 01 13 02 31 ....1x6..m.....1
-| 4064: 7d 25 0f f9 00 08 ff f9 13 31 78 08 87 6b 04 00 .%.......1x..k..
-| 4080: 01 13 02 31 78 33 00 00 00 00 00 08 00 01 00 03 ...1x3..........
-| page 4 offset 12288
-| 0: 0d 00 00 00 03 01 87 00 0b 2d 06 5a 01 87 00 00 .........-.Z....
-| 384: 00 00 00 00 00 00 00 89 50 01 54 00 93 24 00 00 ........P.T..$..
-| 400: 00 32 00 00 00 00 00 00 23 2f 00 00 00 09 00 00 .2......#/......
-| 416: 00 0b 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................
-| 432: 23 2e 00 00 10 09 00 00 00 0b 00 00 00 06 00 00 #...............
-| 448: 00 08 00 00 00 00 00 00 23 2d 00 00 00 09 00 00 ........#-......
-| 464: 00 0b 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................
-| 480: 23 2c 00 00 00 09 00 00 00 0b 00 00 00 04 00 00 #,..............
-| 496: 00 06 00 00 00 00 00 00 23 2b 00 00 00 09 00 00 ........#+......
-| 512: 00 0b 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................
-| 528: 23 2a 00 00 00 09 00 00 00 0b 00 00 00 02 00 00 #*..............
-| 544: 00 04 00 00 00 00 00 00 23 29 00 00 00 09 00 00 ........#)......
-| 560: 00 0b 00 00 00 01 00 00 00 03 00 00 00 00 00 00 ................
-| 576: 1f 4a 00 00 00 08 00 00 00 0a 00 00 00 0a 00 00 .J..............
-| 592: 00 0c 00 00 00 00 00 00 0f 49 00 00 00 08 00 00 .........I......
-| 608: 00 0a 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................
-| 624: 1f 48 00 00 00 08 00 00 00 0a 00 00 00 08 00 06 .H..............
-| 640: 00 0a 00 00 00 00 00 00 1f 47 00 00 00 08 00 00 .........G......
-| 656: 00 0a 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................
-| 672: 15 d6 00 00 00 08 00 00 00 0a 00 00 00 06 00 00 ................
-| 688: 00 08 00 00 00 00 00 00 1f 45 00 00 00 08 00 00 .........E......
-| 704: 00 0a 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................
-| 720: 1f 44 00 00 00 08 00 00 00 0a 00 00 00 04 00 00 .D..............
-| 736: 00 06 00 00 00 00 00 00 1f 43 00 00 00 07 ff ff .........C......
-| 752: f0 0a 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................
-| 768: 1f 42 00 00 00 08 00 00 00 0a 00 00 00 01 ff f0 .B..............
-| 784: 00 03 ff ff ff ff ff ff 1f 41 00 00 00 08 00 00 .........A......
-| 800: 00 0a 00 00 00 01 00 00 00 03 00 00 00 00 00 00 ................
-| 816: 1b 62 00 00 00 07 00 00 00 09 00 00 00 0a 00 00 .b..............
-| 832: 00 0c 05 00 00 00 00 00 1b 64 10 00 00 07 00 00 .........d......
-| 848: 00 09 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................
-| 864: 1b 60 00 00 00 07 00 00 00 09 00 00 00 08 00 00 .`..............
-| 880: 00 0a 00 00 00 00 00 00 1b 5f 00 00 00 07 00 00 ........._......
-| 896: 00 09 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................
-| 912: 1b 5e 00 00 00 07 00 00 00 09 00 00 00 06 00 00 .^..............
-| 928: 00 08 00 00 00 00 00 00 1b 5d 00 00 00 08 00 00 .........]......
-| 944: 00 09 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................
-| 960: 1b 5c 00 00 00 07 00 00 00 09 00 00 00 04 00 00 ................
-| 976: 06 46 00 00 00 00 00 00 1b 5b 00 00 00 07 00 00 .F.......[......
-| 992: 00 09 00 00 00 03 00 00 00 04 ff f0 00 00 00 00 ................
-| 1008: 1b 5a 00 00 00 07 00 00 00 19 00 00 00 02 00 00 .Z..............
-| 1024: 00 04 00 00 00 00 00 00 1b 59 00 00 00 07 00 00 .........Y......
-| 1040: 00 09 00 00 00 01 00 00 00 03 00 00 00 00 ff f0 ................
-| 1056: 17 7a 00 00 00 06 00 00 00 08 00 00 00 0a 00 00 .z..............
-| 1072: 00 0c 00 00 00 00 00 00 17 79 00 00 00 06 00 00 .........y......
-| 1088: 00 08 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................
-| 1104: 17 78 00 00 00 06 00 00 00 08 00 00 00 08 00 00 .x..............
-| 1120: 00 0a 00 00 00 00 00 00 17 77 00 00 00 06 10 00 .........w......
-| 1136: 00 08 00 00 00 07 00 09 c0 09 00 00 00 00 00 00 ................
-| 1152: 17 76 00 00 00 06 00 00 00 08 00 00 00 06 00 00 .v..............
-| 1168: 00 08 00 00 00 00 00 00 17 75 00 00 00 06 00 00 .........u......
-| 1184: 00 08 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................
-| 1200: 17 74 00 00 00 06 00 00 00 08 00 00 00 03 ff ff .t..............
-| 1216: f0 06 00 00 00 83 00 00 17 73 00 00 00 06 00 00 .........s......
-| 1232: 00 08 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................
-| 1248: 17 71 ff 00 00 06 00 00 10 08 00 00 00 02 00 00 .q..............
-| 1264: 00 04 00 00 c0 00 00 00 17 0d 00 00 00 06 00 00 ................
-| 1280: 00 08 00 00 e7 01 00 00 00 03 00 00 09 e0 00 00 ................
-| 1296: 23 30 00 00 00 09 00 00 00 0a 00 00 00 08 00 00 #0..............
-| 1312: 00 0a 00 00 00 00 bb 00 23 31 00 00 00 09 00 00 ........#1......
-| 1328: 00 0b 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................
-| 1344: 23 32 00 00 00 09 00 00 00 0b 00 00 00 0a 00 00 #2..............
-| 1360: 00 0c 00 00 00 00 00 00 27 11 00 00 00 0a 00 00 ........'.......
-| 1376: 00 0c 00 00 00 01 00 08 c0 03 00 00 00 00 00 00 ................
-| 1392: 27 12 00 00 00 0a 00 00 00 0c 51 00 00 02 00 00 '.........Q.....
-| 1408: 00 04 6f 00 00 00 00 00 27 13 00 00 00 09 ff ff ..o.....'.......
-| 1424: 00 0c 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................
-| 1440: 27 14 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 '...............
-| 1616: 00 00 00 00 00 00 00 00 00 00 89 50 02 04 00 93 ...........P....
-| 1632: 24 00 00 00 32 00 00 00 00 00 00 23 8c 00 00 00 $...2......#....
-| 1648: 05 00 00 00 07 00 00 00 04 00 00 00 06 00 00 00 ................
-| 1664: 00 00 00 0f a4 00 00 00 04 00 00 00 06 00 00 00 ................
-| 1680: 04 00 00 00 06 00 00 00 00 00 00 0b bc 00 00 00 ................
-| 1696: 03 00 00 00 05 00 00 00 04 00 00 00 06 00 00 00 ................
-| 1712: 00 00 00 07 d4 00 00 00 02 00 00 00 04 00 00 00 ................
-| 1728: 04 00 00 00 06 00 00 00 10 00 00 03 ec 00 00 00 ................
-| 1744: 01 00 00 00 03 00 00 00 04 00 00 00 06 00 00 00 ................
-| 1760: 00 00 00 13 8d 00 00 00 05 00 00 00 07 00 00 00 ................
-| 1776: 05 00 00 00 07 00 00 00 00 00 00 0f a5 00 00 00 ................
-| 1792: 04 00 00 00 06 00 00 00 05 00 00 00 07 00 00 00 ................
-| 1808: 00 00 00 0b bd 00 00 00 03 00 00 00 05 00 00 00 ................
-| 1824: 05 00 00 00 07 00 00 00 00 00 00 07 d5 00 00 00 ................
-| 1840: 02 00 00 00 05 00 00 00 05 00 00 00 07 00 00 00 ................
-| 1856: 00 00 00 03 ed 00 00 00 01 00 00 00 03 00 00 00 ................
-| 1872: 05 00 00 00 07 00 00 00 00 00 00 13 8e 00 00 00 ................
-| 1888: 05 00 00 00 07 00 00 00 06 00 00 00 08 00 00 00 ................
-| 1904: 00 00 00 0f a6 00 00 00 04 00 00 00 06 00 00 00 ................
-| 1920: 06 00 00 00 07 ff ff 00 00 00 00 0b be 00 00 00 ................
-| 1936: 0b 40 00 00 05 00 00 00 06 00 00 00 08 00 00 00 .@..............
-| 1952: 00 00 00 07 d6 00 00 00 02 00 00 00 04 00 00 00 ................
-| 1968: 05 00 00 00 08 00 00 00 00 00 00 03 ee 00 00 00 ................
-| 1984: 01 00 00 00 02 ff ff 00 06 00 00 00 08 00 00 00 ................
-| 2000: 00 00 00 13 8f 00 00 00 05 00 00 00 07 00 00 00 ................
-| 2016: 07 00 00 00 09 00 00 00 00 00 00 0f a7 00 00 00 ................
-| 2032: 04 00 00 00 06 00 00 00 07 00 00 00 09 00 00 08 ................
-| 2048: 30 00 00 0b bf 00 00 00 03 00 00 00 05 00 00 00 0...............
-| 2064: 07 00 00 00 09 00 00 00 00 00 00 07 d7 00 00 00 ................
-| 2080: 02 00 00 00 04 00 00 00 07 00 00 00 09 00 00 00 ................
-| 2096: 00 00 00 03 ef 00 00 00 01 00 00 00 03 00 00 00 ................
-| 2112: 07 00 00 00 09 00 00 00 00 00 00 13 90 00 00 00 ................
-| 2128: 05 00 01 00 07 00 00 00 08 00 00 00 0a 00 00 00 ................
-| 2144: 00 00 00 0f a8 00 00 00 04 00 00 00 06 00 00 00 ................
-| 2160: 08 00 00 00 0a 00 00 00 00 00 00 0b f2 00 00 00 ................
-| 2176: 03 00 00 00 05 00 00 00 08 00 00 00 0a 00 00 01 ................
-| 2192: 00 00 00 07 d8 00 00 00 02 00 00 00 04 00 00 00 ................
-| 2208: 08 00 00 00 0a 00 00 00 00 00 00 03 f0 00 00 00 ................
-| 2224: 01 00 00 00 03 00 00 00 08 00 00 00 09 ff 00 00 ................
-| 2240: 00 00 00 13 91 00 00 00 05 00 00 00 07 00 00 00 ................
-| 2256: 09 00 00 00 0b 00 00 00 00 00 00 0f a9 00 00 00 ................
-| 2272: 04 00 00 00 06 00 00 00 09 00 00 00 0b 00 00 00 ................
-| 2288: 00 00 00 0b c1 00 00 00 03 00 00 00 05 00 00 00 ................
-| 2304: 09 00 00 00 0b 00 00 00 00 00 00 07 d9 00 00 00 ................
-| 2320: 02 00 00 00 04 00 00 00 09 00 00 00 0b 00 00 01 ................
-| 2336: 00 00 00 03 f0 ff ff 00 01 00 00 00 03 00 00 00 ................
-| 2352: 09 00 00 00 0b 00 00 00 00 00 00 13 92 00 00 00 ................
-| 2368: 05 00 00 00 07 00 00 00 0a 00 00 00 0c 00 00 00 ................
-| 2384: 00 00 00 0f aa 00 00 00 04 00 00 00 06 00 00 00 ................
-| 2400: 0a 00 00 00 0c 00 00 00 00 00 00 0b c2 00 00 00 ................
-| 2416: 03 00 00 00 05 00 00 00 0a 00 00 00 0c 00 00 00 ................
-| 2432: 00 00 00 07 da 00 00 00 02 00 00 00 04 00 00 00 ................
-| 2448: 0a 00 00 00 0c 00 00 00 00 00 00 03 f2 00 00 00 ................
-| 2464: 01 00 00 10 03 00 00 00 0a 00 00 00 0c 00 00 00 ................
-| 2480: 00 00 00 03 eb 00 00 00 01 00 00 00 03 00 00 00 ................
-| 2496: 03 00 00 00 05 00 00 00 00 00 00 07 d3 00 00 00 ................
-| 2512: 02 00 00 00 04 00 00 00 03 00 00 00 05 00 00 00 ................
-| 2528: 00 00 00 0b bb 00 00 00 03 00 00 00 05 00 00 00 ................
-| 2544: 03 00 00 00 05 00 00 00 00 00 00 0f a3 00 00 00 ................
-| 2560: 04 00 00 00 06 00 00 00 03 00 00 00 05 00 00 00 ................
-| 2576: 00 00 00 13 8b 00 00 00 05 00 00 00 07 00 00 00 ................
-| 2592: 03 00 00 00 05 00 00 00 00 00 00 03 ea 00 00 00 ................
-| 2608: 01 00 00 00 03 00 00 00 02 00 00 00 04 00 00 00 ................
-| 2624: 00 00 00 07 d2 00 00 00 02 00 00 00 04 00 00 00 ................
-| 2640: 02 00 00 00 04 00 00 00 00 00 00 0b ba 00 00 00 ................
-| 2656: 03 00 00 00 05 00 00 00 02 00 00 00 04 00 00 00 ................
-| 2672: 00 00 00 0f a1 ff ff ff 04 00 00 00 06 00 00 00 ................
-| 2688: 02 00 00 00 04 00 00 00 00 00 00 13 8a 00 00 00 ................
-| 2704: 05 00 00 00 06 ff ff ff f2 00 00 00 04 00 00 00 ................
-| 2720: 00 00 00 03 e9 00 00 00 01 00 00 00 03 00 00 00 ................
-| 2736: 01 00 00 00 03 00 00 00 00 00 00 07 d1 00 00 00 ................
-| 2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01 ..............P.
-| 2864: 04 00 93 24 00 01 00 02 00 00 00 00 00 00 00 02 ...$............
-| 2880: ff ff ff 06 00 00 00 0c 00 00 00 01 00 00 00 0b ................
-| 2896: 00 00 00 00 00 00 00 02 40 00 00 00 00 00 00 00 ........@.......
-| end crash-2e81f5dce5cbd4.db}]
- execsql { PRAGMA writable_schema = 1;}
- catchsql {UPDATE t1 SET ex= ex ISNULL}
-} {1 {database disk image is malformed}}
-
finish_test
Index: ext/session/sqlite3session.c
==================================================================
--- ext/session/sqlite3session.c
+++ ext/session/sqlite3session.c
@@ -1622,13 +1622,11 @@
}
}
}
sqlite3_free((char*)azCol);
if( bMismatch ){
- if( pzErrMsg ){
- *pzErrMsg = sqlite3_mprintf("table schemas do not match");
- }
+ *pzErrMsg = sqlite3_mprintf("table schemas do not match");
rc = SQLITE_SCHEMA;
}
if( bHasPk==0 ){
/* Ignore tables with no primary keys */
goto diff_out;
@@ -1830,16 +1828,16 @@
**
** If successful, return zero. Otherwise, if an OOM condition is encountered,
** set *pRc to SQLITE_NOMEM and return non-zero.
*/
static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
- if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)nAlloc-p->nBufnAlloc ? p->nAlloc : 128;
do {
nNew = nNew*2;
- }while( (size_t)(nNew-p->nBuf)nBuf)aBuf, nNew);
if( 0==aNew ){
*pRc = SQLITE_NOMEM;
}else{
Index: ext/session/sqlite3session.h
==================================================================
--- ext/session/sqlite3session.h
+++ ext/session/sqlite3session.h
@@ -198,11 +198,11 @@
** METHOD: sqlite3_session
**
** The second argument (xFilter) is the "filter callback". For changes to rows
** in tables that are not attached to the Session object, the filter is called
** to determine whether changes to the table's rows should be tracked or not.
-** If xFilter returns 0, changes are not tracked. Note that once a table is
+** If xFilter returns 0, changes is not tracked. Note that once a table is
** attached, xFilter will not be called again.
*/
void sqlite3session_table_filter(
sqlite3_session *pSession, /* Session object */
int(*xFilter)(
@@ -372,11 +372,11 @@
** identical.
**
** It an error if database zFrom does not exist or does not contain the
** required compatible table.
**
-** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite
+** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite
** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
** may be set to point to a buffer containing an English language error
** message. It is the responsibility of the caller to free this buffer using
** sqlite3_free().
*/
@@ -509,11 +509,11 @@
/*
** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
-** This function may only be used with iterators created by the function
+** This function may only be used with iterators created by function
** [sqlite3changeset_start()]. If it is called on an iterator passed to
** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
** is returned and the call has no effect.
**
** Immediately after an iterator is created by sqlite3changeset_start(), it
@@ -925,12 +925,12 @@
** in the changegroup, then the number of columns and the position of the
** primary key columns for the table must be consistent. If this is not the
** case, this function fails with SQLITE_SCHEMA. If the input changeset
** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
** returned. Or, if an out-of-memory condition occurs during processing, this
-** function returns SQLITE_NOMEM. In all cases, if an error occurs the state
-** of the final contents of the changegroup is undefined.
+** function returns SQLITE_NOMEM. In all cases, if an error occurs the
+** final contents of the changegroup is undefined.
**
** If no error occurs, SQLITE_OK is returned.
*/
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
@@ -1101,11 +1101,11 @@
** [SQLITE_CHANGESET_REPLACE].
**
**
** It is safe to execute SQL statements, including those that write to the
** table that the callback related to, from within the xConflict callback.
-** This can be used to further customize the application's conflict
+** This can be used to further customize the applications conflict
** resolution strategy.
**
** All changes made by these functions are enclosed in a savepoint transaction.
** If any other error (aside from a constraint failure when attempting to
** write to the target database) occurs, then the savepoint transaction is
@@ -1411,11 +1411,11 @@
** CAPI3REF: Rebase a changeset
** EXPERIMENTAL
**
** Argument pIn must point to a buffer containing a changeset nIn bytes
** in size. This function allocates and populates a buffer with a copy
-** of the changeset rebased according to the configuration of the
+** of the changeset rebased rebased according to the configuration of the
** rebaser object passed as the first argument. If successful, (*ppOut)
** is set to point to the new buffer containing the rebased changeset and
** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
** responsibility of the caller to eventually free the new buffer using
** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
Index: ext/userauth/userauth.c
==================================================================
--- ext/userauth/userauth.c
+++ ext/userauth/userauth.c
@@ -38,11 +38,11 @@
){
sqlite3_stmt *pStmt;
char *zSql;
int rc;
va_list ap;
- u64 savedFlags = db->flags;
+ int savedFlags = db->flags;
va_start(ap, zFormat);
zSql = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( zSql==0 ) return 0;
Index: main.mk
==================================================================
--- main.mk
+++ main.mk
@@ -525,10 +525,11 @@
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
+SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
@@ -735,11 +736,10 @@
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/misc/memtrace.c \
- $(TOP)/ext/misc/dbdata.c \
$(TOP)/src/test_windirent.c
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
tclsh $(TOP)/tool/mkshellc.tcl >shell.c
@@ -931,10 +931,14 @@
./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS)
fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
./fuzzcheck$(EXE) $(FUZZDATA)
./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
+
+fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
+ ./fuzzcheck$(EXE) --limit-mem 100M $(FUZZDATA)
+ ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
@@ -949,11 +953,11 @@
quicktest: ./testfixture$(EXE)
./testfixture$(EXE) $(TOP)/test/extraquick.test $(TESTOPTS)
# The default test case. Runs most of the faster standard TCL tests,
# and fuzz tests, and sqlite3_analyzer and sqldiff tests.
-test: fuzztest sourcetest $(TESTPROGS) tcltest
+test: fastfuzztest sourcetest $(TESTPROGS) tcltest
# Run a test using valgrind. This can take a really long time
# because valgrind is so much slower than a native machine.
#
valgrindtest: $(TESTPROGS) valgrindfuzz
Index: src/alter.c
==================================================================
--- src/alter.c
+++ src/alter.c
@@ -51,11 +51,11 @@
*/
static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
sqlite3NestedParse(pParse,
"SELECT 1 "
"FROM \"%w\".%s "
- "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
+ "WHERE name NOT LIKE 'sqlite_%%'"
" AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
zDb, MASTER_NAME,
zDb, bTemp
);
@@ -62,11 +62,11 @@
if( bTemp==0 ){
sqlite3NestedParse(pParse,
"SELECT 1 "
"FROM temp.%s "
- "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
+ "WHERE name NOT LIKE 'sqlite_%%'"
" AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
MASTER_NAME, zDb
);
}
@@ -183,11 +183,11 @@
** the schema to use the new table name. */
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
- "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
+ "AND name NOT LIKE 'sqlite_%%'"
, zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
);
/* Update the tbl_name and name columns of the sqlite_master table
** as required. */
@@ -194,12 +194,11 @@
sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET "
"tbl_name = %Q, "
"name = CASE "
"WHEN type='table' THEN %Q "
- "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
- " AND type='index' THEN "
+ "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
"'sqlite_autoindex_' || %Q || substr(name,%d+18) "
"ELSE name END "
"WHERE tbl_name=%Q COLLATE nocase AND "
"(type='table' OR type='index' OR type='trigger');",
zDb, MASTER_NAME,
@@ -295,10 +294,18 @@
if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
return;
}
#endif
+ /* If the default value for the new column was specified with a
+ ** literal NULL, then set pDflt to 0. This simplifies checking
+ ** for an SQL NULL default below.
+ */
+ assert( pDflt==0 || pDflt->op==TK_SPAN );
+ if( pDflt && pDflt->pLeft->op==TK_NULL ){
+ pDflt = 0;
+ }
/* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
** If there is a NOT NULL constraint, then the default value for the
** column must not be NULL.
*/
@@ -308,53 +315,39 @@
}
if( pNew->pIndex ){
sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
return;
}
- if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
- /* If the default value for the new column was specified with a
- ** literal NULL, then set pDflt to 0. This simplifies checking
- ** for an SQL NULL default below.
- */
- assert( pDflt==0 || pDflt->op==TK_SPAN );
- if( pDflt && pDflt->pLeft->op==TK_NULL ){
- pDflt = 0;
- }
- if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
- sqlite3ErrorMsg(pParse,
- "Cannot add a REFERENCES column with non-NULL default value");
- return;
- }
- if( pCol->notNull && !pDflt ){
- sqlite3ErrorMsg(pParse,
- "Cannot add a NOT NULL column with default value NULL");
- return;
- }
-
- /* Ensure the default expression is something that sqlite3ValueFromExpr()
- ** can handle (i.e. not CURRENT_TIME etc.)
- */
- if( pDflt ){
- sqlite3_value *pVal = 0;
- int rc;
- rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- if( rc!=SQLITE_OK ){
- assert( db->mallocFailed == 1 );
- return;
- }
- if( !pVal ){
- sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default");
- return;
- }
- sqlite3ValueFree(pVal);
- }
- }else if( pCol->colFlags & COLFLAG_STORED ){
- sqlite3ErrorMsg(pParse, "cannot add a STORED column");
- return;
- }
-
+ if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
+ sqlite3ErrorMsg(pParse,
+ "Cannot add a REFERENCES column with non-NULL default value");
+ return;
+ }
+ if( pCol->notNull && !pDflt ){
+ sqlite3ErrorMsg(pParse,
+ "Cannot add a NOT NULL column with default value NULL");
+ return;
+ }
+
+ /* Ensure the default expression is something that sqlite3ValueFromExpr()
+ ** can handle (i.e. not CURRENT_TIME etc.)
+ */
+ if( pDflt ){
+ sqlite3_value *pVal = 0;
+ int rc;
+ rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
+ assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+ if( rc!=SQLITE_OK ){
+ assert( db->mallocFailed == 1 );
+ return;
+ }
+ if( !pVal ){
+ sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
+ return;
+ }
+ sqlite3ValueFree(pVal);
+ }
/* Modify the CREATE TABLE statement. */
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
if( zCol ){
char *zEnd = &zCol[pColDef->n-1];
@@ -438,11 +431,10 @@
}
if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
goto exit_begin_add_column;
}
- sqlite3MayAbort(pParse);
assert( pTab->addColOffset>0 );
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
/* Put a copy of the Table struct in Parse.pNewTable for the
** sqlite3AddColumn() function and friends to modify. But modify
@@ -576,12 +568,11 @@
assert( pNew->n>0 );
bQuote = sqlite3Isquote(pNew->z[0]);
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
- "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
- " AND (type != 'index' OR tbl_name = %Q)"
+ "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
" AND sql NOT LIKE 'create virtual%%'",
zDb, MASTER_NAME,
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
pTab->zName
);
@@ -695,18 +686,16 @@
*/
void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
RenameToken *pNew;
assert( pPtr || pParse->db->mallocFailed );
renameTokenCheckAll(pParse, pPtr);
- if( pParse->eParseMode!=PARSE_MODE_UNMAP ){
- pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
- if( pNew ){
- pNew->p = pPtr;
- pNew->t = *pToken;
- pNew->pNext = pParse->pRename;
- pParse->pRename = pNew;
- }
+ pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
+ if( pNew ){
+ pNew->p = pPtr;
+ pNew->t = *pToken;
+ pNew->pNext = pParse->pRename;
+ pParse->pRename = pNew;
}
return pPtr;
}
@@ -733,71 +722,19 @@
Parse *pParse = pWalker->pParse;
sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
return WRC_Continue;
}
-/*
-** Iterate through the Select objects that are part of WITH clauses attached
-** to select statement pSelect.
-*/
-static void renameWalkWith(Walker *pWalker, Select *pSelect){
- With *pWith = pSelect->pWith;
- if( pWith ){
- int i;
- for(i=0; inCte; i++){
- Select *p = pWith->a[i].pSelect;
- NameContext sNC;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pWalker->pParse;
- sqlite3SelectPrep(sNC.pParse, p, &sNC);
- sqlite3WalkSelect(pWalker, p);
- sqlite3RenameExprlistUnmap(pWalker->pParse, pWith->a[i].pCols);
- }
- }
-}
-
-/*
-** Walker callback used by sqlite3RenameExprUnmap().
-*/
-static int renameUnmapSelectCb(Walker *pWalker, Select *p){
- Parse *pParse = pWalker->pParse;
- int i;
- if( pParse->nErr ) return WRC_Abort;
- if( NEVER(p->selFlags & SF_View) ) return WRC_Prune;
- if( ALWAYS(p->pEList) ){
- ExprList *pList = p->pEList;
- for(i=0; inExpr; i++){
- if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){
- sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);
- }
- }
- }
- if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */
- SrcList *pSrc = p->pSrc;
- for(i=0; inSrc; i++){
- sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
- if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort;
- }
- }
-
- renameWalkWith(pWalker, p);
- return WRC_Continue;
-}
-
/*
** Remove all nodes that are part of expression pExpr from the rename list.
*/
void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
- u8 eMode = pParse->eParseMode;
Walker sWalker;
memset(&sWalker, 0, sizeof(Walker));
sWalker.pParse = pParse;
sWalker.xExprCallback = renameUnmapExprCb;
- sWalker.xSelectCallback = renameUnmapSelectCb;
- pParse->eParseMode = PARSE_MODE_UNMAP;
sqlite3WalkExpr(&sWalker, pExpr);
- pParse->eParseMode = eMode;
}
/*
** Remove all nodes that are part of expression-list pEList from the
** rename list.
@@ -809,13 +746,11 @@
memset(&sWalker, 0, sizeof(Walker));
sWalker.pParse = pParse;
sWalker.xExprCallback = renameUnmapExprCb;
sqlite3WalkExprList(&sWalker, pEList);
for(i=0; inExpr; i++){
- if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){
- sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName);
- }
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName);
}
}
}
/*
@@ -848,18 +783,35 @@
pCtx->nList++;
break;
}
}
}
+
+/*
+** Iterate through the Select objects that are part of WITH clauses attached
+** to select statement pSelect.
+*/
+static void renameWalkWith(Walker *pWalker, Select *pSelect){
+ if( pSelect->pWith ){
+ int i;
+ for(i=0; ipWith->nCte; i++){
+ Select *p = pSelect->pWith->a[i].pSelect;
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pWalker->pParse;
+ sqlite3SelectPrep(sNC.pParse, p, &sNC);
+ sqlite3WalkSelect(pWalker, p);
+ }
+ }
+}
/*
** This is a Walker select callback. It does nothing. It is only required
** because without a dummy callback, sqlite3WalkExpr() and similar do not
** descend into sub-select statements.
*/
static int renameColumnSelectCb(Walker *pWalker, Select *p){
- if( p->selFlags & SF_View ) return WRC_Prune;
renameWalkWith(pWalker, p);
return WRC_Continue;
}
/*
@@ -949,15 +901,12 @@
const char *zOld
){
if( pEList ){
int i;
for(i=0; inExpr; i++){
- char *zName = pEList->a[i].zEName;
- if( ALWAYS(pEList->a[i].eEName==ENAME_NAME)
- && ALWAYS(zName!=0)
- && 0==sqlite3_stricmp(zName, zOld)
- ){
+ char *zName = pEList->a[i].zName;
+ if( 0==sqlite3_stricmp(zName, zOld) ){
renameTokenFind(pParse, pCtx, (void*)zName);
}
}
}
}
@@ -989,10 +938,11 @@
** is initialized by this function before it is used.
*/
static int renameParseSql(
Parse *p, /* Memory to use for Parse object */
const char *zDb, /* Name of schema SQL belongs to */
+ int bTable, /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL to parse */
int bTemp /* True if SQL is from temp schema */
){
int rc;
@@ -1002,11 +952,11 @@
/* Parse the SQL statement passed as the first argument. If no error
** occurs and the parse does not result in a new table, index or
** trigger object, the database must be corrupt. */
memset(p, 0, sizeof(Parse));
- p->eParseMode = PARSE_MODE_RENAME;
+ p->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN);
p->db = db;
p->nQueryLoop = 1;
rc = sqlite3RunParser(p, zSql, &zErr);
assert( p->zErrMsg==0 );
assert( rc!=SQLITE_OK || zErr==0 );
@@ -1309,11 +1259,11 @@
sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol);
#ifndef SQLITE_OMIT_AUTHORIZATION
db->xAuth = 0;
#endif
- rc = renameParseSql(&sParse, zDb, db, zSql, bTemp);
+ rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp);
/* Find tokens that need to be replaced. */
memset(&sWalker, 0, sizeof(Walker));
sWalker.pParse = &sParse;
sWalker.xExprCallback = renameColumnExprCb;
@@ -1323,13 +1273,12 @@
sCtx.pTab = pTab;
if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
if( sParse.pNewTable ){
Select *pSelect = sParse.pNewTable->pSelect;
if( pSelect ){
- pSelect->selFlags &= ~SF_View;
sParse.rc = SQLITE_OK;
- sqlite3SelectPrep(&sParse, pSelect, 0);
+ sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0);
rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
if( rc==SQLITE_OK ){
sqlite3WalkSelect(&sWalker, pSelect);
}
if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
@@ -1352,15 +1301,10 @@
}
for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){
sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
}
}
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- for(i=0; inCol; i++){
- sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt);
- }
-#endif
for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
for(i=0; inCol; i++){
if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
@@ -1442,11 +1386,10 @@
*/
static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
int i;
RenameCtx *p = pWalker->u.pRename;
SrcList *pSrc = pSelect->pSrc;
- if( pSelect->selFlags & SF_View ) return WRC_Prune;
if( pSrc==0 ){
assert( pWalker->pParse->db->mallocFailed );
return WRC_Abort;
}
for(i=0; inSrc; i++){
@@ -1513,32 +1456,26 @@
sWalker.pParse = &sParse;
sWalker.xExprCallback = renameTableExprCb;
sWalker.xSelectCallback = renameTableSelectCb;
sWalker.u.pRename = &sCtx;
- rc = renameParseSql(&sParse, zDb, db, zInput, bTemp);
+ rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
if( rc==SQLITE_OK ){
int isLegacy = (db->flags & SQLITE_LegacyAlter);
if( sParse.pNewTable ){
Table *pTab = sParse.pNewTable;
if( pTab->pSelect ){
if( isLegacy==0 ){
- Select *pSelect = pTab->pSelect;
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = &sParse;
- assert( pSelect->selFlags & SF_View );
- pSelect->selFlags &= ~SF_View;
sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
- if( sParse.nErr ){
- rc = sParse.rc;
- }else{
- sqlite3WalkSelect(&sWalker, pTab->pSelect);
- }
+ if( sParse.nErr ) rc = sParse.rc;
+ sqlite3WalkSelect(&sWalker, pTab->pSelect);
}
}else{
/* Modify any FK definitions to point to the new table. */
#ifndef SQLITE_OMIT_FOREIGN_KEY
if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
@@ -1655,11 +1592,11 @@
UNUSED_PARAMETER(NotUsed);
if( zDb && zInput ){
int rc;
Parse sParse;
- rc = renameParseSql(&sParse, zDb, db, zInput, bTemp);
+ rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
if( rc==SQLITE_OK ){
if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = &sParse;
Index: src/analyze.c
==================================================================
--- src/analyze.c
+++ src/analyze.c
@@ -25,17 +25,17 @@
** Additional tables might be added in future releases of SQLite.
** The sqlite_stat2 table is not created or used unless the SQLite version
** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated.
** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
-** created and used by SQLite versions 3.7.9 through 3.29.0 when
+** created and used by SQLite versions 3.7.9 and later and with
** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3
-** is a superset of sqlite_stat2 and is also now deprecated. The
-** sqlite_stat4 is an enhanced version of sqlite_stat3 and is only
-** available when compiled with SQLITE_ENABLE_STAT4 and in SQLite
-** versions 3.8.1 and later. STAT4 is the only variant that is still
-** supported.
+** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced
+** version of sqlite_stat3 and is only available when compiled with
+** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.1 and later. It is
+** not possible to enable both STAT3 and STAT4 at the same time. If they
+** are both enabled, then STAT4 takes precedence.
**
** For most applications, sqlite_stat1 provides all the statistics required
** for the query planner to make good choices.
**
** Format of sqlite_stat1:
@@ -142,15 +142,21 @@
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"
#if defined(SQLITE_ENABLE_STAT4)
# define IsStat4 1
+# define IsStat3 0
+#elif defined(SQLITE_ENABLE_STAT3)
+# define IsStat4 0
+# define IsStat3 1
#else
# define IsStat4 0
+# define IsStat3 0
# undef SQLITE_STAT4_SAMPLES
# define SQLITE_STAT4_SAMPLES 1
#endif
+#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */
/*
** This routine generates code that opens the sqlite_statN tables.
** The sqlite_stat1 table is always relevant. sqlite_stat2 is now
** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when
@@ -175,14 +181,18 @@
const char *zCols;
} aTable[] = {
{ "sqlite_stat1", "tbl,idx,stat" },
#if defined(SQLITE_ENABLE_STAT4)
{ "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
+ { "sqlite_stat3", 0 },
+#elif defined(SQLITE_ENABLE_STAT3)
+ { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
+ { "sqlite_stat4", 0 },
#else
+ { "sqlite_stat3", 0 },
{ "sqlite_stat4", 0 },
#endif
- { "sqlite_stat3", 0 },
};
int i;
sqlite3 *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite3GetVdbe(pParse);
@@ -259,11 +269,11 @@
typedef struct Stat4Accum Stat4Accum;
typedef struct Stat4Sample Stat4Sample;
struct Stat4Sample {
tRowcnt *anEq; /* sqlite_stat4.nEq */
tRowcnt *anDLt; /* sqlite_stat4.nDLt */
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
tRowcnt *anLt; /* sqlite_stat4.nLt */
union {
i64 iRowid; /* Rowid in main table of the key */
u8 *aRowid; /* Key for WITHOUT ROWID tables */
} u;
@@ -290,11 +300,11 @@
sqlite3 *db; /* Database connection, for malloc() */
};
/* Reclaim memory used by a Stat4Sample
*/
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static void sampleClear(sqlite3 *db, Stat4Sample *p){
assert( db!=0 );
if( p->nRowid ){
sqlite3DbFree(db, p->u.aRowid);
p->nRowid = 0;
@@ -302,11 +312,11 @@
}
#endif
/* Initialize the BLOB value of a ROWID
*/
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
assert( db!=0 );
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
p->u.aRowid = sqlite3DbMallocRawNN(db, n);
if( p->u.aRowid ){
@@ -318,11 +328,11 @@
}
#endif
/* Initialize the INTEGER value of a ROWID.
*/
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
assert( db!=0 );
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
p->nRowid = 0;
p->u.iRowid = iRowid;
@@ -331,11 +341,11 @@
/*
** Copy the contents of object (*pFrom) into (*pTo).
*/
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
pTo->isPSample = pFrom->isPSample;
pTo->iCol = pFrom->iCol;
pTo->iHash = pFrom->iHash;
memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
@@ -352,11 +362,11 @@
/*
** Reclaim all memory of a Stat4Accum structure.
*/
static void stat4Destructor(void *pOld){
Stat4Accum *p = (Stat4Accum*)pOld;
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int i;
for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i);
for(i=0; imxSample; i++) sampleClear(p->db, p->a+i);
sampleClear(p->db, &p->current);
#endif
@@ -372,11 +382,11 @@
**
** Note 1: In the special case of the covering index that implements a
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
** total number of columns in the table.
**
-** Note 2: C is only used for STAT4.
+** Note 2: C is only used for STAT3 and STAT4.
**
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
** PRIMARY KEY of the table. The covering index that implements the
** original WITHOUT ROWID table as N==K as a special case.
@@ -395,11 +405,11 @@
int nCol; /* Number of columns in index being sampled */
int nKeyCol; /* Number of key columns */
int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */
sqlite3 *db; /* Database connection */
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int mxSample = SQLITE_STAT4_SAMPLES;
#endif
/* Decode the three function arguments */
UNUSED_PARAMETER(argc);
@@ -412,11 +422,11 @@
/* Allocate the space required for the Stat4Accum object */
n = sizeof(*p)
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
+ sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
#endif
;
@@ -432,11 +442,11 @@
p->nCol = nCol;
p->nKeyCol = nKeyCol;
p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nColUp];
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
{
u8 *pSpace; /* Allocated space not yet assigned */
int i; /* Used to iterate through p->aSample[] */
p->iGet = -1;
@@ -467,11 +477,11 @@
** (given by the 3rd parameter) is never used and can be any positive
** value. */
sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
}
static const FuncDef statInitFuncdef = {
- 2+IsStat4, /* nArg */
+ 2+IsStat34, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
statInit, /* xSFunc */
0, /* xFinalize */
@@ -507,11 +517,11 @@
if( pNew->iHash>pOld->iHash ) return 1;
return 0;
}
#endif
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Return true if pNew is to be preferred over pOld.
**
** This function assumes that for each argument sample, the contents of
** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid.
@@ -526,15 +536,19 @@
assert( pOld->isPSample==0 && pNew->isPSample==0 );
assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) );
if( (nEqNew>nEqOld) ) return 1;
+#ifdef SQLITE_ENABLE_STAT4
if( nEqNew==nEqOld ){
if( pNew->iColiCol ) return 1;
return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld));
}
return 0;
+#else
+ return (nEqNew==nEqOld && pNew->iHash>pOld->iHash);
+#endif
}
/*
** Copy the contents of sample *pNew into the p->a[] array. If necessary,
** remove the least desirable sample from p->a[] to make room.
@@ -543,10 +557,11 @@
Stat4Sample *pSample = 0;
int i;
assert( IsStat4 || nEqZero==0 );
+#ifdef SQLITE_ENABLE_STAT4
/* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
** values in the anEq[] array of any sample in Stat4Accum.a[]. In
** other words, if nMaxEqZero is n, then it is guaranteed that there
** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
if( nEqZero>p->nMaxEqZero ){
@@ -576,10 +591,11 @@
pUpgrade->iCol = pNew->iCol;
pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol];
goto find_new_min;
}
}
+#endif
/* If necessary, remove sample iMin to make room for the new sample. */
if( p->nSample>=p->mxSample ){
Stat4Sample *pMin = &p->a[p->iMin];
tRowcnt *anEq = pMin->anEq;
@@ -596,22 +612,26 @@
}
/* The "rows less-than" for the rowid column must be greater than that
** for the last sample in the p->a[] array. Otherwise, the samples would
** be out of order. */
+#ifdef SQLITE_ENABLE_STAT4
assert( p->nSample==0
|| pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );
+#endif
/* Insert the new sample */
pSample = &p->a[p->nSample];
sampleCopy(p, pSample, pNew);
p->nSample++;
/* Zero the first nEqZero entries in the anEq[] array. */
memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);
-find_new_min:
+#ifdef SQLITE_ENABLE_STAT4
+ find_new_min:
+#endif
if( p->nSample>=p->mxSample ){
int iMin = -1;
for(i=0; imxSample; i++){
if( p->a[i].isPSample ) continue;
if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){
@@ -620,11 +640,11 @@
}
assert( iMin>=0 );
p->iMin = iMin;
}
}
-#endif /* SQLITE_ENABLE_STAT4 */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** Field iChng of the index being scanned has changed. So at this point
** p->current contains a sample that reflects the previous row of the
** index. The value of anEq[iChng] and subsequent anEq[] elements are
@@ -661,11 +681,32 @@
}
p->nMaxEqZero = iChng;
}
#endif
-#ifndef SQLITE_ENABLE_STAT4
+#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
+ if( iChng==0 ){
+ tRowcnt nLt = p->current.anLt[0];
+ tRowcnt nEq = p->current.anEq[0];
+
+ /* Check if this is to be a periodic sample. If so, add it. */
+ if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){
+ p->current.isPSample = 1;
+ sampleInsert(p, &p->current, 0);
+ p->current.isPSample = 0;
+ }else
+
+ /* Or if it is a non-periodic sample. Add it in this case too. */
+ if( p->nSamplemxSample
+ || sampleIsBetter(p, &p->current, &p->a[p->iMin])
+ ){
+ sampleInsert(p, &p->current, 0);
+ }
+ }
+#endif
+
+#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
UNUSED_PARAMETER( p );
UNUSED_PARAMETER( iChng );
#endif
}
@@ -681,11 +722,11 @@
** This SQL function always returns NULL. It's purpose it to accumulate
** statistical data and/or samples in the Stat4Accum object about the
** index being analyzed. The stat_get() SQL function will later be used to
** extract relevant information for constructing the sqlite_statN tables.
**
-** The R parameter is only used for STAT4
+** The R parameter is only used for STAT3 and STAT4
*/
static void statPush(
sqlite3_context *context,
int argc,
sqlite3_value **argv
@@ -713,18 +754,18 @@
for(i=0; icurrent.anEq[i]++;
}
for(i=iChng; inCol; i++){
p->current.anDLt[i]++;
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
p->current.anLt[i] += p->current.anEq[i];
#endif
p->current.anEq[i] = 1;
}
}
p->nRow++;
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
}else{
sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
sqlite3_value_blob(argv[2]));
@@ -753,11 +794,11 @@
}
}
#endif
}
static const FuncDef statPushFuncdef = {
- 2+IsStat4, /* nArg */
+ 2+IsStat34, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
statPush, /* xSFunc */
0, /* xFinalize */
@@ -784,11 +825,11 @@
** inserted as part of a manually constructed bytecode program. (See
** the callStatGet() routine below.) It is guaranteed that the P
** parameter will always be a poiner to a Stat4Accum object, never a
** NULL.
**
-** If STAT4 is not enabled, then J is always
+** If neither STAT3 nor STAT4 are enabled, then J is always
** STAT_GET_STAT1 and is hence omitted and this routine becomes
** a one-parameter function, stat_get(P), that always returns the
** stat1 table entry information.
*/
static void statGet(
@@ -795,12 +836,12 @@
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
-#ifdef SQLITE_ENABLE_STAT4
- /* STAT4 has a parameter on this routine. */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ /* STAT3 and STAT4 have a parameter on this routine. */
int eCall = sqlite3_value_int(argv[1]);
assert( argc==2 );
assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
|| eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
|| eCall==STAT_GET_NDLT
@@ -851,11 +892,11 @@
}
assert( z[0]=='\0' && z>zRet );
sqlite3_result_text(context, zRet, -1, sqlite3_free);
}
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
else if( eCall==STAT_GET_ROWID ){
if( p->iGet<0 ){
samplePushPrevious(p, 0);
p->iGet = 0;
}
@@ -880,11 +921,13 @@
p->iGet++;
break;
}
}
- {
+ if( IsStat3 ){
+ sqlite3_result_int64(context, (i64)aCnt[0]);
+ }else{
char *zRet = sqlite3MallocZero(p->nCol * 25);
if( zRet==0 ){
sqlite3_result_error_nomem(context);
}else{
int i;
@@ -897,17 +940,17 @@
z[-1] = '\0';
sqlite3_result_text(context, zRet, -1, sqlite3_free);
}
}
}
-#endif /* SQLITE_ENABLE_STAT4 */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
#ifndef SQLITE_DEBUG
UNUSED_PARAMETER( argc );
#endif
}
static const FuncDef statGetFuncdef = {
- 1+IsStat4, /* nArg */
+ 1+IsStat34, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
statGet, /* xSFunc */
0, /* xFinalize */
@@ -914,21 +957,22 @@
0, 0, /* xValue, xInverse */
"stat_get", /* zName */
{0}
};
-static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){
-#ifdef SQLITE_ENABLE_STAT4
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1);
+static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
+ assert( regOut!=regStat4 && regOut!=regStat4+1 );
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
#elif SQLITE_DEBUG
assert( iParam==STAT_GET_STAT1 );
#else
UNUSED_PARAMETER( iParam );
#endif
- assert( regOut!=regStat4 && regOut!=regStat4+1 );
- sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4,
- &statGetFuncdef, 0);
+ sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut,
+ (char*)&statGetFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 1 + IsStat34);
}
/*
** Generate code to do an analysis of all indices associated with
** a single table.
@@ -951,11 +995,11 @@
int iDb; /* Index of database containing pTab */
u8 needTableCnt = 1; /* True to count the table */
int regNewRowid = iMem++; /* Rowid for the inserted record */
int regStat4 = iMem++; /* Register to hold Stat4Accum object */
int regChng = iMem++; /* Index of changed index field */
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
#endif
int regTemp = iMem++; /* Temporary use register */
int regTabname = iMem++; /* Register containing table name */
int regIdxname = iMem++; /* Register containing index name */
@@ -1085,19 +1129,20 @@
** (or for a WITHOUT ROWID table, the number of PK columns),
** (2) the number of columns in the key without the rowid/pk
** (3) the number of rows in the index,
**
**
- ** The third argument is only used for STAT4
+ ** The third argument is only used for STAT3 and STAT4
*/
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
#endif
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
- sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4,
- &statInitFuncdef, 0);
+ sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4,
+ (char*)&statInitFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 2+IsStat34);
/* Implementation of the following:
**
** Rewind csr
** if eof(csr) goto end_of_scan;
@@ -1164,51 +1209,52 @@
sqlite3DbFree(db, aGotoChng);
}
/*
** chng_addr_N:
- ** regRowid = idx(rowid) // STAT4 only
- ** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
+ ** regRowid = idx(rowid) // STAT34 only
+ ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only
** Next csr
** if !eof(csr) goto next_row;
*/
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
assert( regRowid==(regStat4+2) );
if( HasRowid(pTab) ){
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
}else{
Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
int j, k, regKey;
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
for(j=0; jnKeyCol; j++){
- k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
assert( k>=0 && knColumn );
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
}
#endif
assert( regChng==(regStat4+1) );
- sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4,
- &statPushFuncdef, 0);
+ sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp,
+ (char*)&statPushFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 2+IsStat34);
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
/* Add the entry to the stat1 table. */
- callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1);
+ callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
assert( "BBB"[0]==SQLITE_AFF_TEXT );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
#endif
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- /* Add the entries to the stat4 table. */
-#ifdef SQLITE_ENABLE_STAT4
+ /* Add the entries to the stat3 or stat4 table. */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
{
int regEq = regStat1;
int regLt = regStat1+1;
int regDLt = regStat1+2;
int regSample = regStat1+3;
@@ -1219,29 +1265,33 @@
u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
pParse->nMem = MAX(pParse->nMem, regCol+nCol);
addrNext = sqlite3VdbeCurrentAddr(v);
- callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid);
+ callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
VdbeCoverage(v);
- callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq);
- callStatGet(pParse, regStat4, STAT_GET_NLT, regLt);
- callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt);
+ callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
+ callStatGet(v, regStat4, STAT_GET_NLT, regLt);
+ callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
VdbeCoverage(v);
+#ifdef SQLITE_ENABLE_STAT3
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
+#else
for(i=0; i='0' && c<='9' ){
v = v*10 + c - '0';
z++;
}
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( aOut ) aOut[i] = v;
if( aLog ) aLog[i] = sqlite3LogEst(v);
#else
assert( aOut==0 );
UNUSED_PARAMETER(aOut);
@@ -1434,11 +1484,11 @@
assert( aLog!=0 );
aLog[i] = sqlite3LogEst(v);
#endif
if( *z==' ' ) z++;
}
-#ifndef SQLITE_ENABLE_STAT4
+#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
assert( pIndex!=0 ); {
#else
if( pIndex ){
#endif
pIndex->bUnordered = 0;
@@ -1445,13 +1495,11 @@
pIndex->noSkipScan = 0;
while( z[0] ){
if( sqlite3_strglob("unordered*", z)==0 ){
pIndex->bUnordered = 1;
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
- int sz = sqlite3Atoi(z+3);
- if( sz<2 ) sz = 2;
- pIndex->szIdxRow = sqlite3LogEst(sz);
+ pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
pIndex->noSkipScan = 1;
}
#ifdef SQLITE_ENABLE_COSTMULT
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
@@ -1501,11 +1549,11 @@
z = argv[2];
if( pIndex ){
tRowcnt *aiRowEst = 0;
int nCol = pIndex->nKeyCol+1;
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* Index.aiRowEst may already be set here if there are duplicate
** sqlite_stat1 entries for this index. In that case just clobber
** the old data with the new instead of allocating a new array. */
if( pIndex->aiRowEst==0 ){
pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
@@ -1537,11 +1585,11 @@
/*
** If the Index.aSample variable is not NULL, delete the aSample[] array
** and its contents.
*/
void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( pIdx->aSample ){
int j;
for(j=0; jnSample; j++){
IndexSample *p = &pIdx->aSample[j];
sqlite3DbFree(db, p->p);
@@ -1553,14 +1601,14 @@
pIdx->aSample = 0;
}
#else
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pIdx);
-#endif /* SQLITE_ENABLE_STAT4 */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
}
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Populate the pIdx->aAvgEq[] array based on the samples currently
** stored in pIdx->aSample[].
*/
static void initAvgEq(Index *pIdx){
@@ -1634,23 +1682,25 @@
}
return pIdx;
}
/*
-** Load the content from either the sqlite_stat4
+** Load the content from either the sqlite_stat4 or sqlite_stat3 table
** into the relevant Index.aSample[] arrays.
**
** Arguments zSql1 and zSql2 must point to SQL statements that return
-** data equivalent to the following:
+** data equivalent to the following (statements are different for stat3,
+** see the caller of this function for details):
**
** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
**
** where %Q is replaced with the database name before the SQL is executed.
*/
static int loadStatTbl(
sqlite3 *db, /* Database handle */
+ int bStat3, /* Assume single column records only */
const char *zSql1, /* SQL statement 1 (see above) */
const char *zSql2, /* SQL statement 2 (see above) */
const char *zDb /* Database name (e.g. "main") */
){
int rc; /* Result codes from subroutines */
@@ -1680,17 +1730,21 @@
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
nSample = sqlite3_column_int(pStmt, 1);
pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
- assert( pIdx==0 || pIdx->nSample==0 );
- if( pIdx==0 ) continue;
- assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
- if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
- nIdxCol = pIdx->nKeyCol;
- }else{
- nIdxCol = pIdx->nColumn;
+ assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
+ /* Index.nSample is non-zero at this point if data has already been
+ ** loaded from the stat4 table. In this case ignore stat3 data. */
+ if( pIdx==0 || pIdx->nSample ) continue;
+ if( bStat3==0 ){
+ assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
+ if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
+ nIdxCol = pIdx->nKeyCol;
+ }else{
+ nIdxCol = pIdx->nColumn;
+ }
}
pIdx->nSampleCol = nIdxCol;
nByte = sizeof(IndexSample) * nSample;
nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
@@ -1700,10 +1754,11 @@
sqlite3_finalize(pStmt);
return SQLITE_NOMEM_BKPT;
}
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
+ pIdx->pTable->tabFlags |= TF_HasStat4;
for(i=0; iaSample[i].anEq = pSpace; pSpace += nIdxCol;
pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
}
@@ -1728,12 +1783,13 @@
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
if( pIdx==0 ) continue;
/* This next condition is true if data has already been loaded from
- ** the sqlite_stat4 table. */
+ ** the sqlite_stat4 table. In this case ignore stat3 data. */
nCol = pIdx->nSampleCol;
+ if( bStat3 && nCol>1 ) continue;
if( pIdx!=pPrevIdx ){
initAvgEq(pPrevIdx);
pPrevIdx = pIdx;
}
pSample = &pIdx->aSample[pIdx->nSample];
@@ -1762,40 +1818,49 @@
if( rc==SQLITE_OK ) initAvgEq(pPrevIdx);
return rc;
}
/*
-** Load content from the sqlite_stat4 table into
+** Load content from the sqlite_stat4 and sqlite_stat3 tables into
** the Index.aSample[] arrays of all indices.
*/
static int loadStat4(sqlite3 *db, const char *zDb){
int rc = SQLITE_OK; /* Result codes from subroutines */
assert( db->lookaside.bDisable );
if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
- rc = loadStatTbl(db,
+ rc = loadStatTbl(db, 0,
"SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx",
"SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
zDb
);
}
+
+ if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){
+ rc = loadStatTbl(db, 1,
+ "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx",
+ "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3",
+ zDb
+ );
+ }
+
return rc;
}
-#endif /* SQLITE_ENABLE_STAT4 */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
-** Load the content of the sqlite_stat1 and sqlite_stat4 tables. The
+** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
-** arrays. The contents of sqlite_stat4 are used to populate the
+** arrays. The contents of sqlite_stat3/4 are used to populate the
** Index.aSample[] arrays.
**
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
-** is returned. In this case, even if SQLITE_ENABLE_STAT4 was defined
-** during compilation and the sqlite_stat4 table is present, no data is
+** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined
+** during compilation and the sqlite_stat3/4 table is present, no data is
** read from it.
**
-** If SQLITE_ENABLE_STAT4 was defined during compilation and the
+** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the
** sqlite_stat4 table is not present in the database, SQLITE_ERROR is
** returned. However, in this case, data is read from the sqlite_stat1
** table (if it is present) before returning.
**
** If an OOM error occurs, this function always sets db->mallocFailed.
@@ -1819,11 +1884,11 @@
pTab->tabFlags &= ~TF_HasStat1;
}
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
pIdx->hasStat1 = 0;
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
}
@@ -1847,15 +1912,15 @@
Index *pIdx = sqliteHashData(i);
if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
}
/* Load the statistics from the sqlite_stat4 table. */
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( rc==SQLITE_OK ){
- DisableLookaside;
+ db->lookaside.bDisable++;
rc = loadStat4(db, sInfo.zDatabase);
- EnableLookaside;
+ db->lookaside.bDisable--;
}
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3_free(pIdx->aiRowEst);
pIdx->aiRowEst = 0;
Index: src/attach.c
==================================================================
--- src/attach.c
+++ src/attach.c
@@ -297,11 +297,10 @@
){
const char *zName = (const char *)sqlite3_value_text(argv[0]);
sqlite3 *db = sqlite3_context_db_handle(context);
int i;
Db *pDb = 0;
- HashElem *pEntry;
char zErr[128];
UNUSED_PARAMETER(NotUsed);
if( zName==0 ) zName = "";
@@ -322,22 +321,10 @@
if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
- /* If any TEMP triggers reference the schema being detached, move those
- ** triggers to reference the TEMP schema itself. */
- assert( db->aDb[1].pSchema );
- pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash);
- while( pEntry ){
- Trigger *pTrig = (Trigger*)sqliteHashData(pEntry);
- if( pTrig->pTabSchema==pDb->pSchema ){
- pTrig->pTabSchema = pTrig->pSchema;
- }
- pEntry = sqliteHashNext(pEntry);
- }
-
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
sqlite3CollapseDatabaseArray(db);
return;
@@ -399,12 +386,15 @@
sqlite3ExprCode(pParse, pDbname, regArgs+1);
sqlite3ExprCode(pParse, pKey, regArgs+2);
assert( v || db->mallocFailed );
if( v ){
- sqlite3VdbeAddFunctionCall(pParse, 0, regArgs+3-pFunc->nArg, regArgs+3,
- pFunc->nArg, pFunc, 0);
+ sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3,
+ (char *)pFunc, P4_FUNCDEF);
+ assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
+ sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
+
/* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
** statement only). For DETACH, set it to false (expire all existing
** statements).
*/
sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
@@ -475,11 +465,11 @@
pFix->pParse = pParse;
pFix->zDb = db->aDb[iDb].zDbSName;
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
- pFix->bTemp = (iDb==1);
+ pFix->bVarOnly = (iDb==1);
}
/*
** The following set of routines walk through the parse tree and assign
** a specific database to all table references where the database name
@@ -503,21 +493,20 @@
struct SrcList_item *pItem;
if( NEVER(pList==0) ) return 0;
zDb = pFix->zDb;
for(i=0, pItem=pList->a; inSrc; i++, pItem++){
- if( pFix->bTemp==0 ){
+ if( pFix->bVarOnly==0 ){
if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return 1;
}
sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema;
- pItem->fg.fromDDL = 1;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
#endif
@@ -569,11 +558,10 @@
int sqlite3FixExpr(
DbFixer *pFix, /* Context of the fixation */
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
- if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL);
if( pExpr->op==TK_VARIABLE ){
if( pFix->pParse->db->init.busy ){
pExpr->op = TK_NULL;
}else{
sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType);
Index: src/auth.c
==================================================================
--- src/auth.c
+++ src/auth.c
@@ -76,11 +76,11 @@
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
db->xAuth = (sqlite3_xauth)xAuth;
db->pAuthArg = pArg;
- if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1);
+ sqlite3ExpirePreparedStatements(db, 0);
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
/*
Index: src/backup.c
==================================================================
--- src/backup.c
+++ src/backup.c
@@ -272,11 +272,11 @@
** then the backup cannot proceed.
*/
if( nSrcReserve!=nDestReserve ){
u32 newPgsz = nSrcPgsz;
rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
- if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
+ if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
}
#endif
/* This loop runs once for each destination page spanned by the source
** page. For each iteration, variable iOff is set to the byte offset
@@ -617,14 +617,12 @@
if( p->pDestDb ){
p->pSrc->nBackup--;
}
if( p->isAttached ){
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
- assert( pp!=0 );
while( *pp!=p ){
pp = &(*pp)->pNext;
- assert( pp!=0 );
}
*pp = p->pNext;
}
/* If a transaction is still open on the Btree, roll it back. */
Index: src/btree.c
==================================================================
--- src/btree.c
+++ src/btree.c
@@ -697,13 +697,10 @@
assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState );
assert( 0==pCur->pKey );
assert( cursorHoldsMutex(pCur) );
- if( pCur->curFlags & BTCF_Pinned ){
- return SQLITE_CONSTRAINT_PINNED;
- }
if( pCur->eState==CURSOR_SKIPNEXT ){
pCur->eState = CURSOR_VALID;
}else{
pCur->skipNext = 0;
}
@@ -1447,20 +1444,20 @@
u8 *pEnd = &data[cellOffset + nCell*2];
u8 *pAddr;
int sz2 = 0;
int sz = get2byte(&data[iFree+2]);
int top = get2byte(&data[hdr+5]);
- if( NEVER(top>=iFree) ){
+ if( top>=iFree ){
return SQLITE_CORRUPT_PAGE(pPage);
}
if( iFree2 ){
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
sz2 = get2byte(&data[iFree2+2]);
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
sz += sz2;
- }else if( NEVER(iFree+sz>usableSize) ){
+ }else if( iFree+sz>usableSize ){
return SQLITE_CORRUPT_PAGE(pPage);
}
cbrk = top+sz;
assert( cbrk+(iFree-top) <= usableSize );
@@ -1629,11 +1626,11 @@
** and the reserved space is zero (the usual value for reserved space)
** then the cell content offset of an empty page wants to be 65536.
** However, that integer is too large to be stored in a 2-byte unsigned
** integer, so a value of 0 is used in its place. */
top = get2byte(&data[hdr+5]);
- assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
+ assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
if( gap>top ){
if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536;
}else{
return SQLITE_CORRUPT_PAGE(pPage);
@@ -1648,18 +1645,13 @@
testcase( gap+1==top );
testcase( gap==top );
if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){
u8 *pSpace = pageFindSlot(pPage, nByte, &rc);
if( pSpace ){
- int g2;
- assert( pSpace+nByte<=data+pPage->pBt->usableSize );
- *pIdx = g2 = (int)(pSpace-data);
- if( NEVER(g2<=gap) ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }else{
- return SQLITE_OK;
- }
+ assert( pSpace>=data && (pSpace - data)<65536 );
+ *pIdx = (int)(pSpace - data);
+ return SQLITE_OK;
}else if( rc ){
return rc;
}
}
@@ -1729,16 +1721,16 @@
if( data[iPtr+1]==0 && data[iPtr]==0 ){
iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */
}else{
while( (iFreeBlk = get2byte(&data[iPtr]))pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
+ if( iFreeBlk>pPage->pBt->usableSize-4 ){
return SQLITE_CORRUPT_PAGE(pPage);
}
assert( iFreeBlk>iPtr || iFreeBlk==0 );
/* At this point:
@@ -1749,11 +1741,11 @@
*/
if( iFreeBlk && iEnd+3>=iFreeBlk ){
nFrag = iFreeBlk - iEnd;
if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage);
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
- if( NEVER(iEnd > pPage->pBt->usableSize) ){
+ if( iEnd > pPage->pBt->usableSize ){
return SQLITE_CORRUPT_PAGE(pPage);
}
iSize = iEnd - iStart;
iFreeBlk = get2byte(&data[iFreeBlk]);
}
@@ -1777,12 +1769,11 @@
x = get2byte(&data[hdr+5]);
if( iStart<=x ){
/* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another
** freelist entry */
- if( iStart0 ){
u32 next, size;
- if( pcusableSize || nFreeusableSize ){
return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->nFree = (u16)(nFree - iCellFirst);
return SQLITE_OK;
}
@@ -2135,16 +2126,16 @@
/*
** Return the size of the database file in pages. If there is any kind of
** error, return ((unsigned int)-1).
*/
static Pgno btreePagecount(BtShared *pBt){
- assert( (pBt->nPage & 0x80000000)==0 || CORRUPT_DB );
return pBt->nPage;
}
u32 sqlite3BtreeLastPage(Btree *p){
assert( sqlite3BtreeHoldsMutex(p) );
- return btreePagecount(p->pBt) & 0x7fffffff;
+ assert( ((p->pBt->nPage)&0x80000000)==0 );
+ return btreePagecount(p->pBt);
}
/*
** Get a page from the pager and initialize it.
**
@@ -2407,17 +2398,13 @@
memcpy(zFullPathname, zFilename, nFilename);
}else{
rc = sqlite3OsFullPathname(pVfs, zFilename,
nFullPathname, zFullPathname);
if( rc ){
- if( rc==SQLITE_OK_SYMLINK ){
- rc = SQLITE_OK;
- }else{
- sqlite3_free(zFullPathname);
- sqlite3_free(p);
- return rc;
- }
+ sqlite3_free(zFullPathname);
+ sqlite3_free(p);
+ return rc;
}
}
#if SQLITE_THREADSAFE
mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
sqlite3_mutex_enter(mutexOpen);
@@ -4164,22 +4151,10 @@
sqlite3BtreeLeave(pBtree);
}
return rc;
}
-/*
-** Set the pBt->nPage field correctly, according to the current
-** state of the database. Assume pBt->pPage1 is valid.
-*/
-static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
- int nPage = get4byte(&pPage1->aData[28]);
- testcase( nPage==0 );
- if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
- testcase( pBt->nPage!=nPage );
- pBt->nPage = nPage;
-}
-
/*
** Rollback the transaction in progress.
**
** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
** Only write cursors are tripped if writeOnly is true but all cursors are
@@ -4221,11 +4196,15 @@
/* The rollback may have destroyed the pPage1->aData value. So
** call btreeGetPage() on page 1 again to make
** sure pPage1->aData is set correctly. */
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
- btreeSetNPage(pBt, pPage1);
+ int nPage = get4byte(28+(u8*)pPage1->aData);
+ testcase( nPage==0 );
+ if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
+ testcase( pBt->nPage!=nPage );
+ pBt->nPage = nPage;
releasePageOne(pPage1);
}
assert( countValidCursors(pBt, 1)==0 );
pBt->inTransaction = TRANS_READ;
btreeClearHasContent(pBt);
@@ -4301,15 +4280,16 @@
if( rc==SQLITE_OK ){
if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
pBt->nPage = 0;
}
rc = newDatabase(pBt);
- btreeSetNPage(pBt, pBt->pPage1);
+ pBt->nPage = get4byte(28 + pBt->pPage1->aData);
- /* pBt->nPage might be zero if the database was corrupt when
- ** the transaction was started. Otherwise, it must be at least 1. */
- assert( CORRUPT_DB || pBt->nPage>0 );
+ /* The database size was written into the offset 28 of the header
+ ** when the transaction started, so we know that the value at offset
+ ** 28 is nonzero. */
+ assert( pBt->nPage>0 );
}
sqlite3BtreeLeave(p);
}
return rc;
}
@@ -4373,13 +4353,12 @@
);
/* The following assert statements verify that if this is a sharable
** b-tree database, the connection is holding the required table locks,
** and that no other connection has any open cursor that conflicts with
- ** this lock. The iTable<1 term disables the check for corrupt schemas. */
- assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1))
- || iTable<1 );
+ ** this lock. */
+ assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) );
assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
/* Assert that the caller has opened the required transaction. */
assert( p->inTrans>TRANS_NONE );
assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
@@ -4388,17 +4367,13 @@
if( wrFlag ){
allocateTempSpace(pBt);
if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
}
- if( iTable<=1 ){
- if( iTable<1 ){
- return SQLITE_CORRUPT_BKPT;
- }else if( btreePagecount(pBt)==0 ){
- assert( wrFlag==0 );
- iTable = 0;
- }
+ if( iTable==1 && btreePagecount(pBt)==0 ){
+ assert( wrFlag==0 );
+ iTable = 0;
}
/* Now that no other errors can occur, finish filling in the BtCursor
** variables and link the cursor into the BtShared list. */
pCur->pgnoRoot = (Pgno)iTable;
@@ -4419,35 +4394,26 @@
pCur->pNext = pBt->pCursor;
pBt->pCursor = pCur;
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}
-static int btreeCursorWithLock(
- Btree *p, /* The btree */
- int iTable, /* Root page of table to open */
- int wrFlag, /* 1 to write. 0 read-only */
- struct KeyInfo *pKeyInfo, /* First arg to comparison function */
- BtCursor *pCur /* Space for new cursor */
-){
- int rc;
- sqlite3BtreeEnter(p);
- rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
- sqlite3BtreeLeave(p);
- return rc;
-}
int sqlite3BtreeCursor(
Btree *p, /* The btree */
int iTable, /* Root page of table to open */
int wrFlag, /* 1 to write. 0 read-only */
struct KeyInfo *pKeyInfo, /* First arg to xCompare() */
BtCursor *pCur /* Write new cursor here */
){
- if( p->sharable ){
- return btreeCursorWithLock(p, iTable, wrFlag, pKeyInfo, pCur);
+ int rc;
+ if( iTable<1 ){
+ rc = SQLITE_CORRUPT_BKPT;
}else{
- return btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
+ sqlite3BtreeEnter(p);
+ rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
+ sqlite3BtreeLeave(p);
}
+ return rc;
}
/*
** Return the size of a BtCursor object in bytes.
**
@@ -4566,22 +4532,10 @@
assert( pCur->curIntKey );
getCellInfo(pCur);
return pCur->info.nKey;
}
-/*
-** Pin or unpin a cursor.
-*/
-void sqlite3BtreeCursorPin(BtCursor *pCur){
- assert( (pCur->curFlags & BTCF_Pinned)==0 );
- pCur->curFlags |= BTCF_Pinned;
-}
-void sqlite3BtreeCursorUnpin(BtCursor *pCur){
- assert( (pCur->curFlags & BTCF_Pinned)!=0 );
- pCur->curFlags &= ~BTCF_Pinned;
-}
-
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
/*
** Return the offset into the database file for the start of the
** payload to which the cursor is pointing.
*/
@@ -4913,11 +4867,10 @@
u8 aSave[4];
u8 *aWrite = &pBuf[-4];
assert( aWrite>=pBufStart ); /* due to (6) */
memcpy(aSave, aWrite, 4);
rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
- if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT;
nextPage = get4byte(aWrite);
memcpy(aWrite, aSave, 4);
}else
#endif
@@ -5340,11 +5293,10 @@
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
}
assert( pCur->ix==pCur->pPage->nCell-1 );
assert( pCur->pPage->leaf );
#endif
- *pRes = 0;
return SQLITE_OK;
}
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
@@ -5562,11 +5514,10 @@
** up to two varints past the end of the buffer. An extra 18
** bytes of padding is allocated at the end of the buffer in
** case this happens. */
void *pCellKey;
u8 * const pCellBody = pCell - pPage->childPtrSize;
- const int nOverrun = 18; /* Size of the overrun padding */
pPage->xParseCell(pPage, pCellBody, &pCur->info);
nCell = (int)pCur->info.nKey;
testcase( nCell<0 ); /* True if key size is 2^32 or more */
testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
@@ -5573,18 +5524,17 @@
testcase( nCell==2 ); /* Minimum legal index key size */
if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){
rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_finish;
}
- pCellKey = sqlite3Malloc( nCell+nOverrun );
+ pCellKey = sqlite3Malloc( nCell+18 );
if( pCellKey==0 ){
rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
pCur->ix = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
- memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */
pCur->curFlags &= ~BTCF_ValidOvfl;
if( rc ){
sqlite3_free(pCellKey);
goto moveto_finish;
}
@@ -5719,11 +5669,11 @@
}
}
pPage = pCur->pPage;
idx = ++pCur->ix;
- if( !pPage->isInit ){
+ if( !pPage->isInit || sqlite3FaultSim(412) ){
/* The only known way for this to happen is for there to be a
** recursive SQL function that does a DELETE operation as part of a
** SELECT which deletes content out from under an active cursor
** in a corrupt database file where the table being DELETE-ed from
** has pages in common with the table being queried. See TH3
@@ -5734,15 +5684,12 @@
/* If the database file is corrupt, it is possible for the value of idx
** to be invalid here. This can only occur if a second cursor modifies
** the page while cursor pCur is holding a reference to it. Which can
** only happen if the database is corrupt in such a way as to link the
- ** page into more than one b-tree structure.
- **
- ** Update 2019-12-23: appears to long longer be possible after the
- ** addition of anotherValidCursor() condition on balance_deeper(). */
- harmless( idx>pPage->nCell );
+ ** page into more than one b-tree structure. */
+ testcase( idx>pPage->nCell );
if( idx>=pPage->nCell ){
if( !pPage->leaf ){
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
if( rc ) return rc;
@@ -6705,11 +6652,16 @@
assert( MX_CELL(pPage->pBt)<=10921 );
assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB );
+ /* The cell should normally be sized correctly. However, when moving a
+ ** malformed cell from a leaf page to an interior page, if the cell size
+ ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
+ ** might be less than 8 (leaf-size + pointer) on the interior node. Hence
+ ** the term after the || in the following assert(). */
+ assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) );
assert( pPage->nFree>=0 );
if( pPage->nOverflow || sz+2>pPage->nFree ){
if( pTemp ){
memcpy(pTemp, pCell, sz);
pCell = pTemp;
@@ -6963,11 +6915,11 @@
put2byte(pCellptr, (pData - aData));
pCellptr += 2;
if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
memcpy(pData, pCell, sz);
assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
- testcase( sz!=pPg->xCellSize(pPg,pCell) )
+ testcase( sz!=pPg->xCellSize(pPg,pCell) );
i++;
if( i>=iEnd ) break;
if( pCArray->ixNx[k]<=i ){
k++;
pSrcEnd = pCArray->apEnd[k];
@@ -7029,12 +6981,11 @@
for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kapEnd[k];
while( 1 /*Exit by break*/ ){
int sz, rc;
u8 *pSlot;
- assert( pCArray->szCell[i]!=0 );
- sz = pCArray->szCell[i];
+ sz = cachedCellSize(pCArray, i);
if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
if( (pData - pBegin)aCellIdx[iCell * 2];
if( nCell>iCell ){
memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
}
nCell++;
- cachedCellSize(pCArray, iCell+iNew);
if( pageInsertArray(
pPg, pBegin, &pData, pCellptr,
iCell+iNew, 1, pCArray
) ) goto editpage_fail;
}
@@ -7685,11 +7635,10 @@
int limit = pOld->nCell;
u8 *aData = pOld->aData;
u16 maskPage = pOld->maskPage;
u8 *piCell = aData + pOld->cellOffset;
u8 *piEnd;
- VVA_ONLY( int nCellAtStart = b.nCell; )
/* Verify that all sibling pages are of the same "type" (table-leaf,
** table-interior, index-leaf, or index-interior).
*/
if( pOld->aData[0]!=apOld[0]->aData[0] ){
@@ -7714,14 +7663,10 @@
** long be able to find the cells if a pointer to each cell is not saved
** first.
*/
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
if( pOld->nOverflow>0 ){
- if( NEVER(limitaiOvfl[0]) ){
- rc = SQLITE_CORRUPT_BKPT;
- goto balance_cleanup;
- }
limit = pOld->aiOvfl[0];
for(j=0; jnCell+pOld->nOverflow) );
cntOld[i] = b.nCell;
if( i=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0,
nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0
));
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
- assert( nNew>=1 && nNew<=ArraySize(apNew) );
- assert( apNew[nNew-1]!=0 );
put4byte(pRight, apNew[nNew-1]->pgno);
/* If the sibling pages are not leaves, ensure that the right-child pointer
** of the right-most new sibling page is set to the value that was
** originally in the same field of the right-most old sibling page. */
@@ -8040,11 +7982,10 @@
for(i=0; i=0 && iOldnCell + pOld->nOverflow + !leafData;
}
if( i==cntNew[iNew] ){
pNew = apNew[++iNew];
@@ -8327,34 +8268,10 @@
*ppChild = pChild;
return SQLITE_OK;
}
-/*
-** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid
-** on the same B-tree as pCur.
-**
-** This can if a database is corrupt with two or more SQL tables
-** pointing to the same b-tree. If an insert occurs on one SQL table
-** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL
-** table linked to the same b-tree. If the secondary insert causes a
-** rebalance, that can change content out from under the cursor on the
-** first SQL table, violating invariants on the first insert.
-*/
-static int anotherValidCursor(BtCursor *pCur){
- BtCursor *pOther;
- for(pOther=pCur->pBt->pCursor; pOther; pOther=pOther->pNext){
- if( pOther!=pCur
- && pOther->eState==CURSOR_VALID
- && pOther->pPage==pCur->pPage
- ){
- return SQLITE_CORRUPT_BKPT;
- }
- }
- return SQLITE_OK;
-}
-
/*
** The page that pCur currently points to has just been modified in
** some way. This function figures out if this modification means the
** tree needs to be balanced, and if so calls the appropriate balancing
** routine. Balancing routines are:
@@ -8371,18 +8288,16 @@
VVA_ONLY( int balance_quick_called = 0 );
VVA_ONLY( int balance_deeper_called = 0 );
do {
- int iPage;
+ int iPage = pCur->iPage;
MemPage *pPage = pCur->pPage;
if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
- if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
- break;
- }else if( (iPage = pCur->iPage)==0 ){
- if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){
+ if( iPage==0 ){
+ if( pPage->nOverflow ){
/* The root page of the b-tree is overfull. In this case call the
** balance_deeper() function to create a new child for the root-page
** and copy the current contents of the root-page to it. The
** next iteration of the do-loop will balance the child page.
*/
@@ -8398,10 +8313,12 @@
assert( pCur->pPage->nOverflow );
}
}else{
break;
}
+ }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
+ break;
}else{
MemPage * const pParent = pCur->apPage[iPage-1];
int const iIdx = pCur->aiIdx[iPage-1];
rc = sqlite3PagerWrite(pParent->pDbPage);
@@ -8539,13 +8456,11 @@
MemPage *pPage = pCur->pPage; /* Page being written */
BtShared *pBt; /* Btree */
Pgno ovflPgno; /* Next overflow page to write */
u32 ovflPageSize; /* Size to write on overflow page */
- if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd
- || pCur->info.pPayload < pPage->aData + pPage->cellOffset
- ){
+ if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){
return SQLITE_CORRUPT_BKPT;
}
/* Overwrite the local portion first */
rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX,
0, pCur->info.nLocal);
@@ -8674,10 +8589,11 @@
*/
#ifdef SQLITE_DEBUG
if( flags & BTREE_SAVEPOSITION ){
assert( pCur->curFlags & BTCF_ValidNKey );
assert( pX->nKey==pCur->info.nKey );
+ assert( pCur->info.nSize!=0 );
assert( loc==0 );
}
#endif
/* On the other hand, BTREE_SAVEPOSITION==0 does not imply
@@ -8748,13 +8664,11 @@
return btreeOverwriteCell(pCur, &x2);
}
}
}
- assert( pCur->eState==CURSOR_VALID
- || (pCur->eState==CURSOR_INVALID && loc)
- || CORRUPT_DB );
+ assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
pPage = pCur->pPage;
assert( pPage->intKey || pX->nKey>=0 );
assert( pPage->leaf || !pPage->intKey );
if( pPage->nFree<0 ){
@@ -8783,12 +8697,10 @@
oldCell = findCell(pPage, idx);
if( !pPage->leaf ){
memcpy(newCell, oldCell, 4);
}
rc = clearCell(pPage, oldCell, &info);
- testcase( pCur->curFlags & BTCF_ValidOvfl );
- invalidateOverflowCache(pCur);
if( info.nSize==szNew && info.nLocal==info.nPayload
&& (!ISAUTOVACUUM || szNewminLocal)
){
/* Overwrite the old cell with the new if they are the same size.
** We could also try to do this if the old cell is smaller, then add
@@ -8798,16 +8710,11 @@
**
** This optimization cannot be used on an autovacuum database if the
** new entry uses overflow pages, as the insertCell() call below is
** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */
assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
- if( oldCell < pPage->aData+pPage->hdrOffset+10 ){
- return SQLITE_CORRUPT_BKPT;
- }
- if( oldCell+szNew > pPage->aDataEnd ){
- return SQLITE_CORRUPT_BKPT;
- }
+ if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
memcpy(oldCell, newCell, szNew);
return SQLITE_OK;
}
dropCell(pPage, idx, info.nSize, &rc);
if( rc ) goto end_insert;
@@ -9521,11 +9428,11 @@
**
** SQLITE_OK is returned if the operation is successfully executed.
** Otherwise, if an error is encountered (i.e. an IO error or database
** corruption) an SQLite error code is returned.
*/
-int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
+int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
i64 nEntry = 0; /* Value to return in *pnEntry */
int rc; /* Return code */
rc = moveToRoot(pCur);
if( rc==SQLITE_EMPTY ){
@@ -9534,11 +9441,11 @@
}
/* Unless an error occurs, the following loop runs one iteration for each
** page in the B-Tree structure (not including overflow pages).
*/
- while( rc==SQLITE_OK && !db->u1.isInterrupted ){
+ while( rc==SQLITE_OK ){
int iIdx; /* Index of child node in parent */
MemPage *pPage; /* Current page of the b-tree */
/* If this is a leaf page or the tree is not an int-key tree, then
** this page contains countable entries. Increment the entry counter
@@ -9660,11 +9567,10 @@
}
if( getPageReferenced(pCheck, iPage) ){
checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
return 1;
}
- if( pCheck->db->u1.isInterrupted ) return 1;
setPageReferenced(pCheck, iPage);
return 0;
}
#ifndef SQLITE_OMIT_AUTOVACUUM
@@ -10104,11 +10010,10 @@
** allocation errors, an error message held in memory obtained from
** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is
** returned. If a memory allocation error occurs, NULL is returned.
*/
char *sqlite3BtreeIntegrityCheck(
- sqlite3 *db, /* Database connection that is running the check */
Btree *p, /* The btree to be checked */
int *aRoot, /* An array of root pages numbers for individual trees */
int nRoot, /* Number of entries in aRoot[] */
int mxErr, /* Stop reporting errors after this many */
int *pnErr /* Write number of errors seen to this variable */
@@ -10122,11 +10027,10 @@
sqlite3BtreeEnter(p);
assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) );
assert( nRef>=0 );
- sCheck.db = db;
sCheck.pBt = pBt;
sCheck.pPager = pBt->pPager;
sCheck.nPage = btreePagecount(sCheck.pBt);
sCheck.mxErr = mxErr;
sCheck.nErr = 0;
Index: src/btree.h
==================================================================
--- src/btree.h
+++ src/btree.h
@@ -304,21 +304,19 @@
int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int flags);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int flags);
i64 sqlite3BtreeIntegerKey(BtCursor*);
-void sqlite3BtreeCursorPin(BtCursor*);
-void sqlite3BtreeCursorUnpin(BtCursor*);
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
i64 sqlite3BtreeOffset(BtCursor*);
#endif
int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
u32 sqlite3BtreePayloadSize(BtCursor*);
sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
-char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,int*aRoot,int nRoot,int,int*);
+char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
struct Pager *sqlite3BtreePager(Btree*);
i64 sqlite3BtreeRowCountEst(BtCursor*);
#ifndef SQLITE_OMIT_INCRBLOB
int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
@@ -335,11 +333,11 @@
int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
int sqlite3BtreeCursorIsValidNN(BtCursor*);
#ifndef SQLITE_OMIT_BTREECOUNT
-int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
+int sqlite3BtreeCount(BtCursor *, i64 *);
#endif
#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
Index: src/btreeInt.h
==================================================================
--- src/btreeInt.h
+++ src/btreeInt.h
@@ -540,11 +540,10 @@
#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */
#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */
#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */
#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */
#define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */
-#define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */
/*
** Potential values for BtCursor.eState.
**
** CURSOR_INVALID:
@@ -684,11 +683,10 @@
int mallocFailed; /* A memory allocation error has occurred */
const char *zPfx; /* Error message prefix */
int v1, v2; /* Values for up to two %d fields in zPfx */
StrAccum errMsg; /* Accumulate the error message text here */
u32 *heap; /* Min-heap used for analyzing cell coverage */
- sqlite3 *db; /* Database connection running the check */
};
/*
** Routines to read or write a two- and four-byte big-endian integer values.
*/
Index: src/build.c
==================================================================
--- src/build.c
+++ src/build.c
@@ -454,11 +454,11 @@
#endif
sqlite3ExprDelete(db, p->pPartIdxWhere);
sqlite3ExprListDelete(db, p->aColExpr);
sqlite3DbFree(db, p->zColAff);
if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
-#ifdef SQLITE_ENABLE_STAT4
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3_free(p->aiRowEst);
#endif
sqlite3DbFree(db, p);
}
@@ -616,18 +616,14 @@
static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
Index *pIndex, *pNext;
#ifdef SQLITE_DEBUG
/* Record the number of outstanding lookaside allocations in schema Tables
- ** prior to doing any free() operations. Since schema Tables do not use
- ** lookaside, this number should not change.
- **
- ** If malloc has already failed, it may be that it failed while allocating
- ** a Table object that was going to be marked ephemeral. So do not check
- ** that no lookaside memory is used in this case either. */
+ ** prior to doing any free() operations. Since schema Tables do not use
+ ** lookaside, this number should not change. */
int nLookaside = 0;
- if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
+ if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
nLookaside = sqlite3LookasideUsed(db, 0);
}
#endif
/* Delete all indices associated with this table. */
@@ -848,14 +844,12 @@
if( db->init.busy ){
if( sqlite3_stricmp(zType, db->init.azInit[0])
|| sqlite3_stricmp(zName, db->init.azInit[1])
|| sqlite3_stricmp(zTblName, db->init.azInit[2])
){
- if( sqlite3Config.bExtraSchemaChecks ){
- sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */
- return SQLITE_ERROR;
- }
+ sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */
+ return SQLITE_ERROR;
}
}else{
if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7))
|| (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName))
){
@@ -876,101 +870,21 @@
for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){}
return p;
}
/*
-** Convert an table column number into a index column number. That is,
-** for the column iCol in the table (as defined by the CREATE TABLE statement)
-** find the (first) offset of that column in index pIdx. Or return -1
-** if column iCol is not used in index pIdx.
+** Return the column of index pIdx that corresponds to table
+** column iCol. Return -1 if not found.
*/
-i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){
+i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
int i;
for(i=0; inColumn; i++){
if( iCol==pIdx->aiColumn[i] ) return i;
}
return -1;
}
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
-/* Convert a storage column number into a table column number.
-**
-** The storage column number (0,1,2,....) is the index of the value
-** as it appears in the record on disk. The true column number
-** is the index (0,1,2,...) of the column in the CREATE TABLE statement.
-**
-** The storage column number is less than the table column number if
-** and only there are VIRTUAL columns to the left.
-**
-** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro.
-*/
-i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){
- if( pTab->tabFlags & TF_HasVirtual ){
- int i;
- for(i=0; i<=iCol; i++){
- if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++;
- }
- }
- return iCol;
-}
-#endif
-
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
-/* Convert a table column number into a storage column number.
-**
-** The storage column number (0,1,2,....) is the index of the value
-** as it appears in the record on disk. Or, if the input column is
-** the N-th virtual column (zero-based) then the storage number is
-** the number of non-virtual columns in the table plus N.
-**
-** The true column number is the index (0,1,2,...) of the column in
-** the CREATE TABLE statement.
-**
-** If the input column is a VIRTUAL column, then it should not appear
-** in storage. But the value sometimes is cached in registers that
-** follow the range of registers used to construct storage. This
-** avoids computing the same VIRTUAL column multiple times, and provides
-** values for use by OP_Param opcodes in triggers. Hence, if the
-** input column is a VIRTUAL table, put it after all the other columns.
-**
-** In the following, N means "normal column", S means STORED, and
-** V means VIRTUAL. Suppose the CREATE TABLE has columns like this:
-**
-** CREATE TABLE ex(N,S,V,N,S,V,N,S,V);
-** -- 0 1 2 3 4 5 6 7 8
-**
-** Then the mapping from this function is as follows:
-**
-** INPUTS: 0 1 2 3 4 5 6 7 8
-** OUTPUTS: 0 1 6 2 3 7 4 5 8
-**
-** So, in other words, this routine shifts all the virtual columns to
-** the end.
-**
-** If SQLITE_OMIT_GENERATED_COLUMNS then there are no virtual columns and
-** this routine is a no-op macro. If the pTab does not have any virtual
-** columns, then this routine is no-op that always return iCol. If iCol
-** is negative (indicating the ROWID column) then this routine return iCol.
-*/
-i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){
- int i;
- i16 n;
- assert( iColnCol );
- if( (pTab->tabFlags & TF_HasVirtual)==0 || iCol<0 ) return iCol;
- for(i=0, n=0; iaCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++;
- }
- if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ){
- /* iCol is a virtual column itself */
- return pTab->nNVCol + i - n;
- }else{
- /* iCol is a normal or stored column */
- return n;
- }
-}
-#endif
-
/*
** Begin constructing a new table representation in memory. This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement. In particular, this routine is called
** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp
@@ -1257,11 +1171,10 @@
sqlite3Dequote(zType);
pCol->affinity = sqlite3AffinityType(zType, pCol);
pCol->colFlags |= COLFLAG_HASTYPE;
}
p->nCol++;
- p->nNVCol++;
pParse->constraintName.n = 0;
}
/*
** This routine is called by the parser while in the middle of
@@ -1402,21 +1315,14 @@
Table *p;
Column *pCol;
sqlite3 *db = pParse->db;
p = pParse->pNewTable;
if( p!=0 ){
- int isInit = db->init.busy && db->init.iDb!=1;
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){
+ if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- }else if( pCol->colFlags & COLFLAG_GENERATED ){
- testcase( pCol->colFlags & COLFLAG_VIRTUAL );
- testcase( pCol->colFlags & COLFLAG_STORED );
- sqlite3ErrorMsg(pParse, "cannot use DEFAULT on a generated column");
-#endif
}else{
/* A copy of pExpr is used instead of the original, as pExpr contains
** tokens that point to volatile memory.
*/
Expr x;
@@ -1447,11 +1353,11 @@
**
** This is goofy. But to preserve backwards compatibility we continue to
** accept it. This routine does the necessary conversion. It converts
** the expression given in its argument from a TK_STRING into a TK_ID
** if the expression is just a TK_STRING with an optional COLLATE clause.
-** If the expression is anything other than TK_STRING, the expression is
+** If the epxression is anything other than TK_STRING, the expression is
** unchanged.
*/
static void sqlite3StringToId(Expr *p){
if( p->op==TK_STRING ){
p->op = TK_ID;
@@ -1458,25 +1364,10 @@
}else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
p->pLeft->op = TK_ID;
}
}
-/*
-** Tag the given column as being part of the PRIMARY KEY
-*/
-static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){
- pCol->colFlags |= COLFLAG_PRIMKEY;
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- if( pCol->colFlags & COLFLAG_GENERATED ){
- testcase( pCol->colFlags & COLFLAG_VIRTUAL );
- testcase( pCol->colFlags & COLFLAG_STORED );
- sqlite3ErrorMsg(pParse,
- "generated columns cannot be part of the PRIMARY KEY");
- }
-#endif
-}
-
/*
** Designate the PRIMARY KEY for the table. pList is a list of names
** of columns that form the primary key. If pList is NULL, then the
** most recently added column of the table is the primary key.
**
@@ -1512,11 +1403,11 @@
}
pTab->tabFlags |= TF_HasPrimaryKey;
if( pList==0 ){
iCol = pTab->nCol - 1;
pCol = &pTab->aCol[iCol];
- makeColumnPartOfPrimaryKey(pParse, pCol);
+ pCol->colFlags |= COLFLAG_PRIMKEY;
nTerm = 1;
}else{
nTerm = pList->nExpr;
for(i=0; ia[i].pExpr);
@@ -1525,11 +1416,11 @@
if( pCExpr->op==TK_ID ){
const char *zCName = pCExpr->u.zToken;
for(iCol=0; iColnCol; iCol++){
if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
pCol = &pTab->aCol[iCol];
- makeColumnPartOfPrimaryKey(pParse, pCol);
+ pCol->colFlags |= COLFLAG_PRIMKEY;
break;
}
}
}
}
@@ -1545,12 +1436,11 @@
}
pTab->iPKey = iCol;
pTab->keyConf = (u8)onError;
assert( autoInc==0 || autoInc==1 );
pTab->tabFlags |= autoInc*TF_Autoincrement;
- if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags;
- (void)sqlite3HasExplicitNulls(pParse, pList);
+ if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
}else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
"INTEGER PRIMARY KEY");
#endif
@@ -1623,61 +1513,44 @@
}else{
sqlite3DbFree(db, zColl);
}
}
-/* Change the most recently parsed column to be a GENERATED ALWAYS AS
-** column.
+/*
+** This function returns the collation sequence for database native text
+** encoding identified by the string zName, length nName.
+**
+** If the requested collation sequence is not available, or not available
+** in the database native encoding, the collation factory is invoked to
+** request it. If the collation factory does not supply such a sequence,
+** and the sequence is available in another text encoding, then that is
+** returned instead.
+**
+** If no versions of the requested collations sequence are available, or
+** another error occurs, NULL is returned and an error message written into
+** pParse.
+**
+** This routine is a wrapper around sqlite3FindCollSeq(). This routine
+** invokes the collation factory if the named collation cannot be found
+** and generates an error message.
+**
+** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
*/
-void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- u8 eType = COLFLAG_VIRTUAL;
- Table *pTab = pParse->pNewTable;
- Column *pCol;
- if( pTab==0 ){
- /* generated column in an CREATE TABLE IF NOT EXISTS that already exists */
- goto generated_done;
- }
- pCol = &(pTab->aCol[pTab->nCol-1]);
- if( IN_DECLARE_VTAB ){
- sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns");
- goto generated_done;
- }
- if( pCol->pDflt ) goto generated_error;
- if( pType ){
- if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){
- /* no-op */
- }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){
- eType = COLFLAG_STORED;
- }else{
- goto generated_error;
- }
- }
- if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--;
- pCol->colFlags |= eType;
- assert( TF_HasVirtual==COLFLAG_VIRTUAL );
- assert( TF_HasStored==COLFLAG_STORED );
- pTab->tabFlags |= eType;
- if( pCol->colFlags & COLFLAG_PRIMKEY ){
- makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */
- }
- pCol->pDflt = pExpr;
- pExpr = 0;
- goto generated_done;
-
-generated_error:
- sqlite3ErrorMsg(pParse, "error in generated column \"%s\"",
- pCol->zName);
-generated_done:
- sqlite3ExprDelete(pParse->db, pExpr);
-#else
- /* Throw and error for the GENERATED ALWAYS AS clause if the
- ** SQLITE_OMIT_GENERATED_COLUMNS compile-time option is used. */
- sqlite3ErrorMsg(pParse, "generated columns not supported");
- sqlite3ExprDelete(pParse->db, pExpr);
-#endif
-}
+CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
+ sqlite3 *db = pParse->db;
+ u8 enc = ENC(db);
+ u8 initbusy = db->init.busy;
+ CollSeq *pColl;
+
+ pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
+ if( !initbusy && (!pColl || !pColl->xCmp) ){
+ pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
+ }
+
+ return pColl;
+}
+
/*
** Generate code that will increment the schema cookie.
**
** The schema cookie is used to determine when the schema for the
@@ -1877,55 +1750,14 @@
wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
}
pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
}
-/* Return true if column number x is any of the first nCol entries of aiCol[].
-** This is used to determine if the column number x appears in any of the
-** first nCol entries of an index.
+/* Return true if value x is found any of the first nCol entries of aiCol[]
*/
static int hasColumn(const i16 *aiCol, int nCol, int x){
- while( nCol-- > 0 ){
- assert( aiCol[0]>=0 );
- if( x==*(aiCol++) ){
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Return true if any of the first nKey entries of index pIdx exactly
-** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID
-** PRIMARY KEY index. pIdx is an index on the same table. pIdx may
-** or may not be the same index as pPk.
-**
-** The first nKey entries of pIdx are guaranteed to be ordinary columns,
-** not a rowid or expression.
-**
-** This routine differs from hasColumn() in that both the column and the
-** collating sequence must match for this routine, but for hasColumn() only
-** the column name must match.
-*/
-static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
- int i, j;
- assert( nKey<=pIdx->nColumn );
- assert( iColnColumn,pPk->nKeyCol) );
- assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
- assert( pPk->pTable->tabFlags & TF_WithoutRowid );
- assert( pPk->pTable==pIdx->pTable );
- testcase( pPk==pIdx );
- j = pPk->aiColumn[iCol];
- assert( j!=XN_ROWID && j!=XN_EXPR );
- for(i=0; iaiColumn[i]>=0 || j>=0 );
- if( pIdx->aiColumn[i]==j
- && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
- ){
- return 1;
- }
- }
+ while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
return 0;
}
/* Recompute the colNotIdxed field of the Index.
**
@@ -1932,28 +1764,19 @@
** colNotIdxed is a bitmask that has a 0 bit representing each indexed
** columns that are within the first 63 columns of the table. The
** high-order bit of colNotIdxed is always 1. All unindexed columns
** of the table have a 1.
**
-** 2019-10-24: For the purpose of this computation, virtual columns are
-** not considered to be covered by the index, even if they are in the
-** index, because we do not trust the logic in whereIndexExprTrans() to be
-** able to find all instances of a reference to the indexed table column
-** and convert them into references to the index. Hence we always want
-** the actual table at hand in order to recompute the virtual column, if
-** necessary.
-**
** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask
** to determine if the index is covering index.
*/
static void recomputeColumnsNotIndexed(Index *pIdx){
Bitmask m = 0;
int j;
- Table *pTab = pIdx->pTable;
for(j=pIdx->nColumn-1; j>=0; j--){
int x = pIdx->aiColumn[j];
- if( x>=0 && (pTab->aCol[x].colFlags & COLFLAG_VIRTUAL)==0 ){
+ if( x>=0 ){
testcase( x==BMS-1 );
testcase( x==BMS-2 );
if( xdb;
Vdbe *v = pParse->pVdbe;
/* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
@@ -2000,11 +1822,10 @@
for(i=0; inCol; i++){
if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){
pTab->aCol[i].notNull = OE_Abort;
}
}
- pTab->tabFlags |= TF_HasNotNull;
}
/* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
** into BTREE_BLOBKEY.
*/
@@ -2021,21 +1842,17 @@
Token ipkToken;
sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
if( pList==0 ) return;
- if( IN_RENAME_OBJECT ){
- sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
- }
- pList->a[0].sortFlags = pParse->iPkSortOrder;
+ pList->a[0].sortOrder = pParse->iPkSortOrder;
assert( pParse->pNewTable==pTab );
- pTab->iPKey = -1;
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
SQLITE_IDXTYPE_PRIMARYKEY);
if( db->mallocFailed || pParse->nErr ) return;
pPk = sqlite3PrimaryKeyIndex(pTab);
- assert( pPk->nKeyCol==1 );
+ pTab->iPKey = -1;
}else{
pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pPk!=0 );
/*
@@ -2042,25 +1859,22 @@
** Remove all redundant columns from the PRIMARY KEY. For example, change
** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
** code assumes the PRIMARY KEY contains no repeated columns.
*/
for(i=j=1; inKeyCol; i++){
- if( isDupColumn(pPk, j, pPk, i) ){
+ if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
pPk->nColumn--;
}else{
- testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
- pPk->azColl[j] = pPk->azColl[i];
- pPk->aSortOrder[j] = pPk->aSortOrder[i];
pPk->aiColumn[j++] = pPk->aiColumn[i];
}
}
pPk->nKeyCol = j;
}
assert( pPk!=0 );
pPk->isCovering = 1;
if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
- nPk = pPk->nColumn = pPk->nKeyCol;
+ nPk = pPk->nKeyCol;
/* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
** table entry. This is only required if currently generating VDBE
** code for a CREATE TABLE (not when parsing one as part of reading
** a database schema). */
@@ -2077,57 +1891,46 @@
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int n;
if( IsPrimaryKeyIndex(pIdx) ) continue;
for(i=n=0; inKeyCol, pPk, i) ){
- testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
- n++;
- }
+ if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
}
if( n==0 ){
/* This index is a superset of the primary key */
pIdx->nColumn = pIdx->nKeyCol;
continue;
}
if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
for(i=0, j=pIdx->nKeyCol; inKeyCol, pPk, i) ){
- testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
+ if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
pIdx->aiColumn[j] = pPk->aiColumn[i];
pIdx->azColl[j] = pPk->azColl[i];
- if( pPk->aSortOrder[i] ){
- /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */
- pIdx->bAscKeyBug = 1;
- }
j++;
}
}
assert( pIdx->nColumn>=pIdx->nKeyCol+n );
assert( pIdx->nColumn>=j );
}
/* Add all table columns to the PRIMARY KEY index
*/
- nExtra = 0;
- for(i=0; inCol; i++){
- if( !hasColumn(pPk->aiColumn, nPk, i)
- && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++;
- }
- if( resizeIndexObject(db, pPk, nPk+nExtra) ) return;
- for(i=0, j=nPk; inCol; i++){
- if( !hasColumn(pPk->aiColumn, j, i)
- && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0
- ){
- assert( jnColumn );
- pPk->aiColumn[j] = i;
- pPk->azColl[j] = sqlite3StrBINARY;
- j++;
- }
- }
- assert( pPk->nColumn==j );
- assert( pTab->nNVCol<=j );
+ if( nPknCol ){
+ if( resizeIndexObject(db, pPk, pTab->nCol) ) return;
+ for(i=0, j=nPk; inCol; i++){
+ if( !hasColumn(pPk->aiColumn, j, i) ){
+ assert( jnColumn );
+ pPk->aiColumn[j] = i;
+ pPk->azColl[j] = sqlite3StrBINARY;
+ j++;
+ }
+ }
+ assert( pPk->nColumn==j );
+ assert( pTab->nCol==j );
+ }else{
+ pPk->nColumn = pTab->nCol;
+ }
recomputeColumnsNotIndexed(pPk);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
@@ -2230,61 +2033,25 @@
"AUTOINCREMENT not allowed on WITHOUT ROWID tables");
return;
}
if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
- return;
+ }else{
+ p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
+ convertToWithoutRowidTable(pParse, p);
}
- p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
- convertToWithoutRowidTable(pParse, p);
}
+
iDb = sqlite3SchemaToIndex(db, p->pSchema);
#ifndef SQLITE_OMIT_CHECK
/* Resolve names in all CHECK constraint expressions.
*/
if( p->pCheck ){
sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
- if( pParse->nErr ){
- /* If errors are seen, delete the CHECK constraints now, else they might
- ** actually be used if PRAGMA writable_schema=ON is set. */
- sqlite3ExprListDelete(db, p->pCheck);
- p->pCheck = 0;
- }
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- if( p->tabFlags & TF_HasGenerated ){
- int ii, nNG = 0;
- testcase( p->tabFlags & TF_HasVirtual );
- testcase( p->tabFlags & TF_HasStored );
- for(ii=0; iinCol; ii++){
- u32 colFlags = p->aCol[ii].colFlags;
- if( (colFlags & COLFLAG_GENERATED)!=0 ){
- Expr *pX = p->aCol[ii].pDflt;
- testcase( colFlags & COLFLAG_VIRTUAL );
- testcase( colFlags & COLFLAG_STORED );
- if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){
- /* If there are errors in resolving the expression, change the
- ** expression to a NULL. This prevents code generators that operate
- ** on the expression from inserting extra parts into the expression
- ** tree that have been allocated from lookaside memory, which is
- ** illegal in a schema and will lead to errors or heap corruption
- ** when the database connection closes. */
- sqlite3ExprDelete(db, pX);
- p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
- }
- }else{
- nNG++;
- }
- }
- if( nNG==0 ){
- sqlite3ErrorMsg(pParse, "must have at least one non-generated column");
- return;
- }
- }
-#endif
/* Estimate the average row size for the table and for all implied indices */
estimateTableWidth(p);
for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
estimateIndexWidth(pIdx);
@@ -2354,14 +2121,14 @@
sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
pParse->nTab = 2;
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
if( pParse->nErr ) return;
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB);
+ pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
if( pSelTab==0 ) return;
assert( p->aCol==0 );
- p->nCol = p->nNVCol = pSelTab->nCol;
+ p->nCol = pSelTab->nCol;
p->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite3DeleteTable(db, pSelTab);
sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
@@ -2429,10 +2196,11 @@
/* Reparse everything to update our internal data structures */
sqlite3VdbeAddParseSchemaOp(v, iDb,
sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName));
}
+
/* Add the table to the in-memory representation of the database.
*/
if( db->init.busy ){
Table *pOld;
@@ -2500,11 +2268,10 @@
/* Make a copy of the entire SELECT statement that defines the view.
** This will force all the Expr.token.z values to be dynamically
** allocated rather than point to the input string - which means that
** they will persist after the current sqlite3_exec() call returns.
*/
- pSelect->selFlags |= SF_View;
if( IN_RENAME_OBJECT ){
p->pSelect = pSelect;
pSelect = 0;
}else{
p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
@@ -2614,24 +2381,21 @@
pParse->eParseMode = PARSE_MODE_NORMAL;
#endif
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
- DisableLookaside;
+ db->lookaside.bDisable++;
#ifndef SQLITE_OMIT_AUTHORIZATION
xAuth = db->xAuth;
db->xAuth = 0;
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
+ pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
db->xAuth = xAuth;
#else
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
+ pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
#endif
pParse->nTab = n;
- if( pSelTab==0 ){
- pTable->nCol = 0;
- nErr++;
- }else if( pTable->pCheck ){
+ if( pTable->pCheck ){
/* CREATE VIEW name(arglist) AS ...
** The names of the columns in the table are taken from
** arglist which is stored in pTable->pCheck. The pCheck field
** normally holds CHECK constraints on an ordinary table, but for
** a VIEW it holds the list of column names.
@@ -2640,28 +2404,29 @@
&pTable->nCol, &pTable->aCol);
if( db->mallocFailed==0
&& pParse->nErr==0
&& pTable->nCol==pSel->pEList->nExpr
){
- sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
- SQLITE_AFF_NONE);
+ sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
}
- }else{
+ }else if( pSelTab ){
/* CREATE VIEW name AS... without an argument list. Construct
** the column names from the SELECT statement that defines the view.
*/
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
pTable->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
+ }else{
+ pTable->nCol = 0;
+ nErr++;
}
- pTable->nNVCol = pTable->nCol;
sqlite3DeleteTable(db, pSelTab);
sqlite3SelectDelete(db, pSel);
- EnableLookaside;
+ db->lookaside.bDisable--;
#ifndef SQLITE_OMIT_ALTERTABLE
pParse->eParseMode = eParseMode;
#endif
} else {
nErr++;
@@ -3106,11 +2871,11 @@
nCol = pFromCol->nExpr;
}
nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1;
if( pToCol ){
for(i=0; inExpr; i++){
- nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1;
+ nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1;
}
}
pFKey = sqlite3DbMallocZero(db, nByte );
if( pFKey==0 ){
goto fk_end;
@@ -3131,34 +2896,34 @@
pFKey->aCol[0].iFrom = p->nCol-1;
}else{
for(i=0; inCol; j++){
- if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zEName)==0 ){
+ if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
pFKey->aCol[i].iFrom = j;
break;
}
}
if( j>=p->nCol ){
sqlite3ErrorMsg(pParse,
"unknown column \"%s\" in foreign key definition",
- pFromCol->a[i].zEName);
+ pFromCol->a[i].zName);
goto fk_end;
}
if( IN_RENAME_OBJECT ){
- sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zEName);
+ sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName);
}
}
}
if( pToCol ){
for(i=0; ia[i].zEName);
+ int n = sqlite3Strlen30(pToCol->a[i].zName);
pFKey->aCol[i].zCol = z;
if( IN_RENAME_OBJECT ){
- sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zEName);
+ sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName);
}
- memcpy(z, pToCol->a[i].zEName, n);
+ memcpy(z, pToCol->a[i].zName, n);
z[n] = 0;
z += n+1;
}
}
pFKey->isDeferred = 0;
@@ -3284,31 +3049,14 @@
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
pIndex->nKeyCol); VdbeCoverage(v);
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
sqlite3VdbeJumpHere(v, j2);
}else{
- /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not
- ** abort. The exception is if one of the indexed expressions contains a
- ** user function that throws an exception when it is evaluated. But the
- ** overhead of adding a statement journal to a CREATE INDEX statement is
- ** very small (since most of the pages written do not contain content that
- ** needs to be restored if the statement aborts), so we call
- ** sqlite3MayAbort() for all CREATE INDEX statements. */
- sqlite3MayAbort(pParse);
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
- if( !pIndex->bAscKeyBug ){
- /* This OP_SeekEnd opcode makes index insert for a REINDEX go much
- ** faster by avoiding unnecessary seeks. But the optimization does
- ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables
- ** with DESC primary keys, since those indexes have there keys in
- ** a different order from the main table.
- ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf
- */
- sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
- }
+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
@@ -3351,31 +3099,10 @@
*ppExtra = ((char*)p) + nByte;
}
return p;
}
-/*
-** If expression list pList contains an expression that was parsed with
-** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in
-** pParse and return non-zero. Otherwise, return zero.
-*/
-int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){
- if( pList ){
- int i;
- for(i=0; inExpr; i++){
- if( pList->a[i].bNulls ){
- u8 sf = pList->a[i].sortFlags;
- sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s",
- (sf==0 || sf==3) ? "FIRST" : "LAST"
- );
- return 1;
- }
- }
- }
- return 0;
-}
-
/*
** Create a new index for an SQL table. pName1.pName2 is the name of the index
** and pTblList is the name of the table that is to be indexed. Both will
** be NULL for a primary key or an index that is created to satisfy a
** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable
@@ -3423,13 +3150,10 @@
goto exit_create_index;
}
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_create_index;
}
- if( sqlite3HasExplicitNulls(pParse, pList) ){
- goto exit_create_index;
- }
/*
** Find the table that is to be indexed. Return early if not found.
*/
if( pTblName!=0 ){
@@ -3590,11 +3314,11 @@
sqlite3TokenInit(&prevCol, pCol->zName);
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
if( pList==0 ) goto exit_create_index;
assert( pList->nExpr==1 );
- sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED);
+ sqlite3ExprListSetSortOrder(pList, sortOrder);
}else{
sqlite3ExprListCheckLength(pParse, pList, "index");
if( pParse->nErr ) goto exit_create_index;
}
@@ -3685,17 +3409,12 @@
}else{
j = pCExpr->iColumn;
assert( j<=0x7fff );
if( j<0 ){
j = pTab->iPKey;
- }else{
- if( pTab->aCol[j].notNull==0 ){
- pIndex->uniqNotNull = 0;
- }
- if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){
- pIndex->bHasVCol = 1;
- }
+ }else if( pTab->aCol[j].notNull==0 ){
+ pIndex->uniqNotNull = 0;
}
pIndex->aiColumn[i] = (i16)j;
}
zColl = 0;
if( pListItem->pExpr->op==TK_COLLATE ){
@@ -3713,11 +3432,11 @@
if( !zColl ) zColl = sqlite3StrBINARY;
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
- requestedSortOrder = pListItem->sortFlags & sortOrderMask;
+ requestedSortOrder = pListItem->sortOrder & sortOrderMask;
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
}
/* Append the table key to the end of the index. For WITHOUT ROWID
** tables (when pPk!=0) this will be the declared PRIMARY KEY. For
@@ -3725,14 +3444,13 @@
*/
if( pPk ){
for(j=0; jnKeyCol; j++){
int x = pPk->aiColumn[j];
assert( x>=0 );
- if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
+ if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
pIndex->nColumn--;
}else{
- testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
pIndex->aiColumn[i] = x;
pIndex->azColl[i] = pPk->azColl[j];
pIndex->aSortOrder[i] = pPk->aSortOrder[j];
i++;
}
@@ -3746,17 +3464,17 @@
if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
/* If this index contains every column of its table, then mark
** it as a covering index */
assert( HasRowid(pTab)
- || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 );
+ || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
recomputeColumnsNotIndexed(pIndex);
if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
pIndex->isCovering = 1;
for(j=0; jnCol; j++){
if( j==pTab->iPKey ) continue;
- if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue;
+ if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue;
pIndex->isCovering = 0;
break;
}
}
@@ -3888,11 +3606,10 @@
sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY);
/* Gather the complete text of the CREATE INDEX statement into
** the zStmt variable
*/
- assert( pName!=0 || pStart==0 );
if( pStart ){
int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
if( pName->z[n-1]==';' ) n--;
/* A named index with an explicit CREATE INDEX statement */
zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
@@ -3927,13 +3644,30 @@
}
sqlite3VdbeJumpHere(v, pIndex->tnum);
}
}
+
+ /* When adding an index to the list of indices for a table, make
+ ** sure all indices labeled OE_Replace come after all those labeled
+ ** OE_Ignore. This is necessary for the correct constraint check
+ ** processing (in sqlite3GenerateConstraintChecks()) as part of
+ ** UPDATE and INSERT statements.
+ */
if( db->init.busy || pTblName==0 ){
- pIndex->pNext = pTab->pIndex;
- pTab->pIndex = pIndex;
+ if( onError!=OE_Replace || pTab->pIndex==0
+ || pTab->pIndex->onError==OE_Replace){
+ pIndex->pNext = pTab->pIndex;
+ pTab->pIndex = pIndex;
+ }else{
+ Index *pOther = pTab->pIndex;
+ while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
+ pOther = pOther->pNext;
+ }
+ pIndex->pNext = pOther->pNext;
+ pOther->pNext = pIndex;
+ }
pIndex = 0;
}
else if( IN_RENAME_OBJECT ){
assert( pParse->pNewIndex==0 );
pParse->pNewIndex = pIndex;
@@ -3941,25 +3675,10 @@
}
/* Clean up before exiting */
exit_create_index:
if( pIndex ) sqlite3FreeIndex(db, pIndex);
- if( pTab ){ /* Ensure all REPLACE indexes are at the end of the list */
- Index **ppFrom = &pTab->pIndex;
- Index *pThis;
- for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){
- Index *pNext;
- if( pThis->onError!=OE_Replace ) continue;
- while( (pNext = pThis->pNext)!=0 && pNext->onError!=OE_Replace ){
- *ppFrom = pNext;
- pThis->pNext = pNext->pNext;
- pNext->pNext = pThis;
- ppFrom = &pNext->pNext;
- }
- break;
- }
- }
sqlite3ExprDelete(db, pPIWhere);
sqlite3ExprListDelete(db, pList);
sqlite3SrcListDelete(db, pTblName);
sqlite3DbFree(db, zName);
}
@@ -4929,12 +4648,11 @@
assert( sqlite3KeyInfoIsWriteable(pKey) );
for(i=0; iazColl[i];
pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
sqlite3LocateCollSeq(pParse, zColl);
- pKey->aSortFlags[i] = pIdx->aSortOrder[i];
- assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) );
+ pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
if( pParse->nErr ){
assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
if( pIdx->bNoQuery==0 ){
/* Deactivate the index because it contains an unknown collating
Index: src/callback.c
==================================================================
--- src/callback.c
+++ src/callback.c
@@ -62,10 +62,55 @@
return SQLITE_OK;
}
}
return SQLITE_ERROR;
}
+
+/*
+** This function is responsible for invoking the collation factory callback
+** or substituting a collation sequence of a different encoding when the
+** requested collation sequence is not available in the desired encoding.
+**
+** If it is not NULL, then pColl must point to the database native encoding
+** collation sequence with name zName, length nName.
+**
+** The return value is either the collation sequence to be used in database
+** db for collation type name zName, length nName, or NULL, if no collation
+** sequence can be found. If no collation is found, leave an error message.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
+*/
+CollSeq *sqlite3GetCollSeq(
+ Parse *pParse, /* Parsing context */
+ u8 enc, /* The desired encoding for the collating sequence */
+ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
+ const char *zName /* Collating sequence name */
+){
+ CollSeq *p;
+ sqlite3 *db = pParse->db;
+
+ p = pColl;
+ if( !p ){
+ p = sqlite3FindCollSeq(db, enc, zName, 0);
+ }
+ if( !p || !p->xCmp ){
+ /* No collation sequence of this type for this encoding is registered.
+ ** Call the collation factory to see if it can supply us with one.
+ */
+ callCollNeeded(db, enc, zName);
+ p = sqlite3FindCollSeq(db, enc, zName, 0);
+ }
+ if( p && !p->xCmp && synthCollSeq(db, p) ){
+ p = 0;
+ }
+ assert( !p || p->xCmp );
+ if( p==0 ){
+ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
+ pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ;
+ }
+ return p;
+}
/*
** This routine is called on a collation sequence before it is used to
** check that it is defined. An undefined collation sequence exists when
** a database is loaded that contains references to collation sequences
@@ -155,14 +200,14 @@
** cannot be found.
**
** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
*/
CollSeq *sqlite3FindCollSeq(
- sqlite3 *db, /* Database connection to search */
- u8 enc, /* Desired text encoding */
- const char *zName, /* Name of the collating sequence. Might be NULL */
- int create /* True to create CollSeq if doesn't already exist */
+ sqlite3 *db,
+ u8 enc,
+ const char *zName,
+ int create
){
CollSeq *pColl;
if( zName ){
pColl = findCollSeqEntry(db, zName, create);
}else{
@@ -169,89 +214,10 @@
pColl = db->pDfltColl;
}
assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
if( pColl ) pColl += enc-1;
- return pColl;
-}
-
-/*
-** This function is responsible for invoking the collation factory callback
-** or substituting a collation sequence of a different encoding when the
-** requested collation sequence is not available in the desired encoding.
-**
-** If it is not NULL, then pColl must point to the database native encoding
-** collation sequence with name zName, length nName.
-**
-** The return value is either the collation sequence to be used in database
-** db for collation type name zName, length nName, or NULL, if no collation
-** sequence can be found. If no collation is found, leave an error message.
-**
-** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
-*/
-CollSeq *sqlite3GetCollSeq(
- Parse *pParse, /* Parsing context */
- u8 enc, /* The desired encoding for the collating sequence */
- CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
- const char *zName /* Collating sequence name */
-){
- CollSeq *p;
- sqlite3 *db = pParse->db;
-
- p = pColl;
- if( !p ){
- p = sqlite3FindCollSeq(db, enc, zName, 0);
- }
- if( !p || !p->xCmp ){
- /* No collation sequence of this type for this encoding is registered.
- ** Call the collation factory to see if it can supply us with one.
- */
- callCollNeeded(db, enc, zName);
- p = sqlite3FindCollSeq(db, enc, zName, 0);
- }
- if( p && !p->xCmp && synthCollSeq(db, p) ){
- p = 0;
- }
- assert( !p || p->xCmp );
- if( p==0 ){
- sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
- pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ;
- }
- return p;
-}
-
-/*
-** This function returns the collation sequence for database native text
-** encoding identified by the string zName.
-**
-** If the requested collation sequence is not available, or not available
-** in the database native encoding, the collation factory is invoked to
-** request it. If the collation factory does not supply such a sequence,
-** and the sequence is available in another text encoding, then that is
-** returned instead.
-**
-** If no versions of the requested collations sequence are available, or
-** another error occurs, NULL is returned and an error message written into
-** pParse.
-**
-** This routine is a wrapper around sqlite3FindCollSeq(). This routine
-** invokes the collation factory if the named collation cannot be found
-** and generates an error message.
-**
-** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
-*/
-CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
- sqlite3 *db = pParse->db;
- u8 enc = ENC(db);
- u8 initbusy = db->init.busy;
- CollSeq *pColl;
-
- pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
- if( !initbusy && (!pColl || !pColl->xCmp) ){
- pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
- }
-
return pColl;
}
/* During the search for the best function definition, this procedure
** is called to test how well the function passed as the first argument
@@ -286,17 +252,16 @@
FuncDef *p, /* The function we are evaluating for match quality */
int nArg, /* Desired number of arguments. (-1)==any */
u8 enc /* Desired text encoding */
){
int match;
- assert( p->nArg>=-1 );
+
+ /* nArg of -2 is a special case */
+ if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH;
/* Wrong number of arguments means "no match" */
- if( p->nArg!=nArg ){
- if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH;
- if( p->nArg>=0 ) return 0;
- }
+ if( p->nArg!=nArg && p->nArg>=0 ) return 0;
/* Give a better score to a function with a specific number of arguments
** than to function that accepts any number of arguments. */
if( p->nArg==nArg ){
match = 4;
Index: src/ctime.c
==================================================================
--- src/ctime.c
+++ src/ctime.c
@@ -12,11 +12,11 @@
**
** This file implements routines used to report what compile-time options
** SQLite was built with.
*/
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* IMP: R-16824-07538 */
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
*/
@@ -304,10 +304,12 @@
#if SQLITE_ENABLE_SQLLOG
"ENABLE_SQLLOG",
#endif
#if defined(SQLITE_ENABLE_STAT4)
"ENABLE_STAT4",
+#elif defined(SQLITE_ENABLE_STAT3)
+ "ENABLE_STAT3",
#endif
#if SQLITE_ENABLE_STMTVTAB
"ENABLE_STMTVTAB",
#endif
#if SQLITE_ENABLE_STMT_SCANSTATUS
Index: src/date.c
==================================================================
--- src/date.c
+++ src/date.c
@@ -386,11 +386,11 @@
return 0;
}else if( parseHhMmSs(zDate, p)==0 ){
return 0;
}else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
return setDateTimeToCurrent(context, p);
- }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
+ }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
setRawDateNumber(p, r);
return 0;
}
return 1;
}
@@ -686,11 +686,11 @@
*/
if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
r = p->s*1000.0 + 210866760000000.0;
if( r>=0.0 && r<464269060800000.0 ){
clearYMD_HMS_TZ(p);
- p->iJD = (sqlite3_int64)(r + 0.5);
+ p->iJD = (sqlite3_int64)r;
p->validJD = 1;
p->rawS = 0;
rc = 0;
}
}
@@ -720,11 +720,11 @@
** Move the date to the same time on the next occurrence of
** weekday N where 0==Sunday, 1==Monday, and so forth. If the
** date is already on the appropriate weekday, this is a no-op.
*/
if( sqlite3_strnicmp(z, "weekday ", 8)==0
- && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
+ && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
&& (n=(int)r)==r && n>=0 && r<7 ){
sqlite3_int64 Z;
computeYMD_HMS(p);
p->validTZ = 0;
p->validJD = 0;
@@ -779,11 +779,11 @@
case '8':
case '9': {
double rRounder;
int i;
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
- if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
+ if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
rc = 1;
break;
}
if( z[n]==':' ){
/* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
Index: src/dbpage.c
==================================================================
--- src/dbpage.c
+++ src/dbpage.c
@@ -71,11 +71,10 @@
char **pzErr
){
DbpageTable *pTab = 0;
int rc = SQLITE_OK;
- sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
if( rc==SQLITE_OK ){
pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
Index: src/dbstat.c
==================================================================
--- src/dbstat.c
+++ src/dbstat.c
@@ -10,11 +10,11 @@
**
******************************************************************************
**
** This file contains an implementation of the "dbstat" virtual table.
**
-** The dbstat virtual table is used to extract low-level storage
+** The dbstat virtual table is used to extract low-level formatting
** information from an SQLite database in order to implement the
** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script
** for an example implementation.
**
** Additional information is available on the "dbstat.html" page of the
@@ -54,98 +54,90 @@
** the overflow pages associated with a cell will appear earlier in the
** sort-order than its child page:
**
** '/1c2/000/' // Left-most child of 451st child of root
*/
-static const char zDbstatSchema[] =
- "CREATE TABLE x("
- " name TEXT," /* 0 Name of table or index */
- " path TEXT," /* 1 Path to page from root (NULL for agg) */
- " pageno INTEGER," /* 2 Page number (page count for aggregates) */
- " pagetype TEXT," /* 3 'internal', 'leaf', 'overflow', or NULL */
- " ncell INTEGER," /* 4 Cells on page (0 for overflow) */
- " payload INTEGER," /* 5 Bytes of payload on this page */
- " unused INTEGER," /* 6 Bytes of unused space on this page */
- " mx_payload INTEGER," /* 7 Largest payload size of all cells */
- " pgoffset INTEGER," /* 8 Offset of page in file (NULL for agg) */
- " pgsize INTEGER," /* 9 Size of the page (sum for aggregate) */
- " schema TEXT HIDDEN," /* 10 Database schema being analyzed */
- " aggregate BOOLEAN HIDDEN" /* 11 aggregate info for each table */
- ")"
-;
-
-/* Forward reference to data structured used in this module */
+#define VTAB_SCHEMA \
+ "CREATE TABLE xx( " \
+ " name TEXT, /* Name of table or index */" \
+ " path TEXT, /* Path to page from root */" \
+ " pageno INTEGER, /* Page number */" \
+ " pagetype TEXT, /* 'internal', 'leaf' or 'overflow' */" \
+ " ncell INTEGER, /* Cells on page (0 for overflow) */" \
+ " payload INTEGER, /* Bytes of payload on this page */" \
+ " unused INTEGER, /* Bytes of unused space on this page */" \
+ " mx_payload INTEGER, /* Largest payload size of all cells */" \
+ " pgoffset INTEGER, /* Offset of page in file */" \
+ " pgsize INTEGER, /* Size of the page */" \
+ " schema TEXT HIDDEN /* Database schema being analyzed */" \
+ ");"
+
+
typedef struct StatTable StatTable;
typedef struct StatCursor StatCursor;
typedef struct StatPage StatPage;
typedef struct StatCell StatCell;
-/* Size information for a single cell within a btree page */
struct StatCell {
int nLocal; /* Bytes of local payload */
u32 iChildPg; /* Child node (or 0 if this is a leaf) */
int nOvfl; /* Entries in aOvfl[] */
u32 *aOvfl; /* Array of overflow page numbers */
int nLastOvfl; /* Bytes of payload on final overflow page */
int iOvfl; /* Iterates through aOvfl[] */
};
-/* Size information for a single btree page */
struct StatPage {
- u32 iPgno; /* Page number */
- DbPage *pPg; /* Page content */
- int iCell; /* Current cell */
+ u32 iPgno;
+ DbPage *pPg;
+ int iCell;
char *zPath; /* Path to this page */
/* Variables populated by statDecodePage(): */
u8 flags; /* Copy of flags byte */
int nCell; /* Number of cells on page */
int nUnused; /* Number of unused bytes on page */
StatCell *aCell; /* Array of parsed cells */
u32 iRightChildPg; /* Right-child page number (or 0) */
- int nMxPayload; /* Largest payload of any cell on the page */
+ int nMxPayload; /* Largest payload of any cell on this page */
};
-/* The cursor for scanning the dbstat virtual table */
struct StatCursor {
- sqlite3_vtab_cursor base; /* base class. MUST BE FIRST! */
+ sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt; /* Iterates through set of root pages */
- u8 isEof; /* After pStmt has returned SQLITE_DONE */
- u8 isAgg; /* Aggregate results for each table */
+ int isEof; /* After pStmt has returned SQLITE_DONE */
int iDb; /* Schema used for this query */
- StatPage aPage[32]; /* Pages in path to current page */
+ StatPage aPage[32];
int iPage; /* Current entry in aPage[] */
/* Values to return. */
- u32 iPageno; /* Value of 'pageno' column */
char *zName; /* Value of 'name' column */
char *zPath; /* Value of 'path' column */
+ u32 iPageno; /* Value of 'pageno' column */
char *zPagetype; /* Value of 'pagetype' column */
- int nPage; /* Number of pages in current btree */
int nCell; /* Value of 'ncell' column */
+ int nPayload; /* Value of 'payload' column */
+ int nUnused; /* Value of 'unused' column */
int nMxPayload; /* Value of 'mx_payload' column */
- i64 nUnused; /* Value of 'unused' column */
- i64 nPayload; /* Value of 'payload' column */
i64 iOffset; /* Value of 'pgOffset' column */
- i64 szPage; /* Value of 'pgSize' column */
+ int szPage; /* Value of 'pgSize' column */
};
-/* An instance of the DBSTAT virtual table */
struct StatTable {
- sqlite3_vtab base; /* base class. MUST BE FIRST! */
- sqlite3 *db; /* Database connection that owns this vtab */
+ sqlite3_vtab base;
+ sqlite3 *db;
int iDb; /* Index of database to analyze */
};
#ifndef get2byte
# define get2byte(x) ((x)[0]<<8 | (x)[1])
#endif
/*
-** Connect to or create a new DBSTAT virtual table.
+** Connect to or create a statvfs virtual table.
*/
static int statConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
@@ -165,12 +157,11 @@
return SQLITE_ERROR;
}
}else{
iDb = 0;
}
- sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
- rc = sqlite3_declare_vtab(db, zDbstatSchema);
+ rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
if( rc==SQLITE_OK ){
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
}
@@ -184,73 +175,43 @@
*ppVtab = (sqlite3_vtab*)pTab;
return rc;
}
/*
-** Disconnect from or destroy the DBSTAT virtual table.
+** Disconnect from or destroy a statvfs virtual table.
*/
static int statDisconnect(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return SQLITE_OK;
}
/*
-** Compute the best query strategy and return the result in idxNum.
+** There is no "best-index". This virtual table always does a linear
+** scan. However, a schema=? constraint should cause this table to
+** operate on a different database schema, so check for it.
**
-** idxNum-Bit Meaning
-** ---------- ----------------------------------------------
-** 0x01 There is a schema=? term in the WHERE clause
-** 0x02 There is a name=? term in the WHERE clause
-** 0x04 There is an aggregate=? term in the WHERE clause
-** 0x08 Output should be ordered by name and path
+** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
*/
static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int i;
- int iSchema = -1;
- int iName = -1;
- int iAgg = -1;
/* Look for a valid schema=? constraint. If found, change the idxNum to
** 1 and request the value of that constraint be sent to xFilter. And
** lower the cost estimate to encourage the constrained version to be
** used.
*/
for(i=0; inConstraint; i++){
+ if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
+ if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT;
if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
- if( pIdxInfo->aConstraint[i].usable==0 ){
- /* Force DBSTAT table should always be the right-most table in a join */
- return SQLITE_CONSTRAINT;
- }
- switch( pIdxInfo->aConstraint[i].iColumn ){
- case 0: { /* name */
- iName = i;
- break;
- }
- case 10: { /* schema */
- iSchema = i;
- break;
- }
- case 11: { /* aggregate */
- iAgg = i;
- break;
- }
- }
- }
- i = 0;
- if( iSchema>=0 ){
- pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i;
- pIdxInfo->idxNum |= 0x01;
- }
- if( iName>=0 ){
- pIdxInfo->aConstraintUsage[iName].argvIndex = ++i;
- pIdxInfo->idxNum |= 0x02;
- }
- if( iAgg>=0 ){
- pIdxInfo->aConstraintUsage[iAgg].argvIndex = ++i;
- pIdxInfo->idxNum |= 0x04;
- }
- pIdxInfo->estimatedCost = 1.0;
+ pIdxInfo->idxNum = 1;
+ pIdxInfo->estimatedCost = 1.0;
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ break;
+ }
+
/* Records are always returned in ascending order of (name, path).
** If this will satisfy the client, set the orderByConsumed flag so that
** SQLite does not do an external sort.
*/
@@ -264,18 +225,17 @@
&& pIdxInfo->aOrderBy[1].iColumn==1
&& pIdxInfo->aOrderBy[1].desc==0
)
){
pIdxInfo->orderByConsumed = 1;
- pIdxInfo->idxNum |= 0x08;
}
return SQLITE_OK;
}
/*
-** Open a new DBSTAT cursor.
+** Open a new statvfs cursor.
*/
static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
StatTable *pTab = (StatTable *)pVTab;
StatCursor *pCsr;
@@ -321,40 +281,26 @@
sqlite3_free(pCsr->zPath);
pCsr->zPath = 0;
pCsr->isEof = 0;
}
-/* Resize the space-used counters inside of the cursor */
-static void statResetCounts(StatCursor *pCsr){
- pCsr->nCell = 0;
- pCsr->nMxPayload = 0;
- pCsr->nUnused = 0;
- pCsr->nPayload = 0;
- pCsr->szPage = 0;
- pCsr->nPage = 0;
-}
-
/*
-** Close a DBSTAT cursor.
+** Close a statvfs cursor.
*/
static int statClose(sqlite3_vtab_cursor *pCursor){
StatCursor *pCsr = (StatCursor *)pCursor;
statResetCsr(pCsr);
sqlite3_finalize(pCsr->pStmt);
sqlite3_free(pCsr);
return SQLITE_OK;
}
-/*
-** For a single cell on a btree page, compute the number of bytes of
-** content (payload) stored on that page. That is to say, compute the
-** number of bytes of content not found on overflow pages.
-*/
-static int getLocalPayload(
+static void getLocalPayload(
int nUsable, /* Usable bytes per page */
u8 flags, /* Page flags */
- int nTotal /* Total record (payload) size */
+ int nTotal, /* Total record (payload) size */
+ int *pnLocal /* OUT: Bytes stored locally */
){
int nLocal;
int nMinLocal;
int nMaxLocal;
@@ -366,16 +312,13 @@
nMaxLocal = (nUsable - 12) * 64 / 255 - 23;
}
nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4);
if( nLocal>nMaxLocal ) nLocal = nMinLocal;
- return nLocal;
+ *pnLocal = nLocal;
}
-/* Populate the StatPage object with information about the all
-** cells found on the page currently under analysis.
-*/
static int statDecodePage(Btree *pBt, StatPage *p){
int nUnused;
int iOff;
int nHdr;
int isLeaf;
@@ -442,11 +385,11 @@
if( p->flags==0x0D ){
u64 dummy;
iOff += sqlite3GetVarint(&aData[iOff], &dummy);
}
if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
- nLocal = getLocalPayload(nUsable, p->flags, nPayload);
+ getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
if( nLocal<0 ) goto statPageIsCorrupt;
pCell->nLocal = nLocal;
assert( nPayload>=(u32)nLocal );
assert( nLocal<=(nUsable-35) );
if( nPayload>(u32)nLocal ){
@@ -492,29 +435,27 @@
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3_file *fd;
sqlite3_int64 x[2];
- /* If connected to a ZIPVFS backend, find the page size and
- ** offset from ZIPVFS.
+ /* The default page size and offset */
+ pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
+ pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
+
+ /* If connected to a ZIPVFS backend, override the page size and
+ ** offset with actual values obtained from ZIPVFS.
*/
fd = sqlite3PagerFile(pPager);
x[0] = pCsr->iPageno;
if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
pCsr->iOffset = x[0];
- pCsr->szPage += x[1];
- }else{
- /* Not ZIPVFS: The default page size and offset */
- pCsr->szPage += sqlite3BtreeGetPageSize(pBt);
- pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
+ pCsr->szPage = (int)x[1];
}
}
/*
-** Move a DBSTAT cursor to the next entry. Normally, the next
-** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0),
-** the next entry is the next btree.
+** Move a statvfs cursor to the next entry in the file.
*/
static int statNext(sqlite3_vtab_cursor *pCursor){
int rc;
int nPayload;
char *z;
@@ -526,12 +467,10 @@
sqlite3_free(pCsr->zPath);
pCsr->zPath = 0;
statNextRestart:
if( pCsr->aPage[0].pPg==0 ){
- /* Start measuring space on the next btree */
- statResetCounts(pCsr);
rc = sqlite3_step(pCsr->pStmt);
if( rc==SQLITE_ROW ){
int nPage;
u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
sqlite3PagerPagecount(pPager, &nPage);
@@ -540,65 +479,57 @@
return sqlite3_reset(pCsr->pStmt);
}
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0);
pCsr->aPage[0].iPgno = iRoot;
pCsr->aPage[0].iCell = 0;
- if( !pCsr->isAgg ){
- pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
- if( z==0 ) rc = SQLITE_NOMEM_BKPT;
- }
+ pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
pCsr->iPage = 0;
- pCsr->nPage = 1;
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
}else{
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
}
}else{
- /* Continue analyzing the btree previously started */
+
+ /* Page p itself has already been visited. */
StatPage *p = &pCsr->aPage[pCsr->iPage];
- if( !pCsr->isAgg ) statResetCounts(pCsr);
+
while( p->iCellnCell ){
StatCell *pCell = &p->aCell[p->iCell];
- while( pCell->iOvflnOvfl ){
- int nUsable, iOvfl;
+ if( pCell->iOvflnOvfl ){
+ int nUsable;
sqlite3BtreeEnter(pBt);
nUsable = sqlite3BtreeGetPageSize(pBt) -
sqlite3BtreeGetReserveNoMutex(pBt);
sqlite3BtreeLeave(pBt);
- pCsr->nPage++;
- statSizeAndOffset(pCsr);
+ pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
+ pCsr->iPageno = pCell->aOvfl[pCell->iOvfl];
+ pCsr->zPagetype = "overflow";
+ pCsr->nCell = 0;
+ pCsr->nMxPayload = 0;
+ pCsr->zPath = z = sqlite3_mprintf(
+ "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
+ );
if( pCell->iOvflnOvfl-1 ){
- pCsr->nPayload += nUsable - 4;
+ pCsr->nUnused = 0;
+ pCsr->nPayload = nUsable - 4;
}else{
- pCsr->nPayload += pCell->nLastOvfl;
- pCsr->nUnused += nUsable - 4 - pCell->nLastOvfl;
+ pCsr->nPayload = pCell->nLastOvfl;
+ pCsr->nUnused = nUsable - 4 - pCsr->nPayload;
}
- iOvfl = pCell->iOvfl;
pCell->iOvfl++;
- if( !pCsr->isAgg ){
- pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
- pCsr->iPageno = pCell->aOvfl[iOvfl];
- pCsr->zPagetype = "overflow";
- pCsr->zPath = z = sqlite3_mprintf(
- "%s%.3x+%.6x", p->zPath, p->iCell, iOvfl
- );
- return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
- }
+ statSizeAndOffset(pCsr);
+ return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
}
if( p->iRightChildPg ) break;
p->iCell++;
}
if( !p->iRightChildPg || p->iCell>p->nCell ){
statClearPage(p);
- if( pCsr->iPage>0 ){
- pCsr->iPage--;
- }else if( pCsr->isAgg ){
- /* label-statNext-done: When computing aggregate space usage over
- ** an entire btree, this is the exit point from this function */
- return SQLITE_OK;
- }
+ if( pCsr->iPage==0 ) return statNext(pCursor);
+ pCsr->iPage--;
goto statNextRestart; /* Tail recursion */
}
pCsr->iPage++;
if( pCsr->iPage>=ArraySize(pCsr->aPage) ){
statResetCsr(pCsr);
@@ -610,17 +541,14 @@
p[1].iPgno = p->iRightChildPg;
}else{
p[1].iPgno = p->aCell[p->iCell].iChildPg;
}
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0);
- pCsr->nPage++;
p[1].iCell = 0;
- if( !pCsr->isAgg ){
- p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
- if( z==0 ) rc = SQLITE_NOMEM_BKPT;
- }
+ p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
p->iCell++;
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
}
/* Populate the StatCursor fields with the values to be returned
** by the xColumn() and xRowid() methods.
@@ -646,27 +574,20 @@
break;
default:
pCsr->zPagetype = "corrupted";
break;
}
- pCsr->nCell += p->nCell;
- pCsr->nUnused += p->nUnused;
- if( p->nMxPayload>pCsr->nMxPayload ) pCsr->nMxPayload = p->nMxPayload;
- if( !pCsr->isAgg ){
- pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
- if( z==0 ) rc = SQLITE_NOMEM_BKPT;
- }
+ pCsr->nCell = p->nCell;
+ pCsr->nUnused = p->nUnused;
+ pCsr->nMxPayload = p->nMxPayload;
+ pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
nPayload = 0;
for(i=0; inCell; i++){
nPayload += p->aCell[i].nLocal;
}
- pCsr->nPayload += nPayload;
-
- /* If computing aggregate space usage by btree, continue with the
- ** next page. The loop will exit via the return at label-statNext-done
- */
- if( pCsr->isAgg ) goto statNextRestart;
+ pCsr->nPayload = nPayload;
}
}
return rc;
}
@@ -674,67 +595,40 @@
static int statEof(sqlite3_vtab_cursor *pCursor){
StatCursor *pCsr = (StatCursor *)pCursor;
return pCsr->isEof;
}
-/* Initialize a cursor according to the query plan idxNum using the
-** arguments in argv[0]. See statBestIndex() for a description of the
-** meaning of the bits in idxNum.
-*/
static int statFilter(
sqlite3_vtab_cursor *pCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
StatCursor *pCsr = (StatCursor *)pCursor;
StatTable *pTab = (StatTable*)(pCursor->pVtab);
- sqlite3_str *pSql; /* Query of btrees to analyze */
- char *zSql; /* String value of pSql */
- int iArg = 0; /* Count of argv[] parameters used so far */
- int rc = SQLITE_OK; /* Result of this operation */
- const char *zName = 0; /* Only provide analysis of this table */
-
- statResetCsr(pCsr);
- sqlite3_finalize(pCsr->pStmt);
- pCsr->pStmt = 0;
- if( idxNum & 0x01 ){
- /* schema=? constraint is present. Get its value */
- const char *zDbase = (const char*)sqlite3_value_text(argv[iArg++]);
+ char *zSql;
+ int rc = SQLITE_OK;
+
+ if( idxNum==1 ){
+ const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase);
if( pCsr->iDb<0 ){
- pCsr->iDb = 0;
- pCsr->isEof = 1;
- return SQLITE_OK;
+ sqlite3_free(pCursor->pVtab->zErrMsg);
+ pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
+ return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM_BKPT;
}
}else{
pCsr->iDb = pTab->iDb;
}
- if( idxNum & 0x02 ){
- /* name=? constraint is present */
- zName = (const char*)sqlite3_value_text(argv[iArg++]);
- }
- if( idxNum & 0x04 ){
- /* aggregate=? constraint is present */
- pCsr->isAgg = sqlite3_value_double(argv[iArg++])!=0.0;
- }else{
- pCsr->isAgg = 0;
- }
- pSql = sqlite3_str_new(pTab->db);
- sqlite3_str_appendf(pSql,
- "SELECT * FROM ("
- "SELECT 'sqlite_master' AS name,1 AS rootpage,'table' AS type"
- " UNION ALL "
- "SELECT name,rootpage,type"
- " FROM \"%w\".sqlite_master WHERE rootpage!=0)",
- pTab->db->aDb[pCsr->iDb].zDbSName);
- if( zName ){
- sqlite3_str_appendf(pSql, "WHERE name=%Q", zName);
- }
- if( idxNum & 0x08 ){
- sqlite3_str_appendf(pSql, " ORDER BY name");
- }
- zSql = sqlite3_str_finish(pSql);
+ statResetCsr(pCsr);
+ sqlite3_finalize(pCsr->pStmt);
+ pCsr->pStmt = 0;
+ zSql = sqlite3_mprintf(
+ "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
+ " UNION ALL "
+ "SELECT name, rootpage, type"
+ " FROM \"%w\".sqlite_master WHERE rootpage!=0"
+ " ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName);
if( zSql==0 ){
return SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
@@ -755,25 +649,17 @@
switch( i ){
case 0: /* name */
sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
break;
case 1: /* path */
- if( !pCsr->isAgg ){
- sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
- }
+ sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
break;
case 2: /* pageno */
- if( pCsr->isAgg ){
- sqlite3_result_int64(ctx, pCsr->nPage);
- }else{
- sqlite3_result_int64(ctx, pCsr->iPageno);
- }
+ sqlite3_result_int64(ctx, pCsr->iPageno);
break;
case 3: /* pagetype */
- if( !pCsr->isAgg ){
- sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
- }
+ sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
break;
case 4: /* ncell */
sqlite3_result_int(ctx, pCsr->nCell);
break;
case 5: /* payload */
@@ -784,27 +670,21 @@
break;
case 7: /* mx_payload */
sqlite3_result_int(ctx, pCsr->nMxPayload);
break;
case 8: /* pgoffset */
- if( !pCsr->isAgg ){
- sqlite3_result_int64(ctx, pCsr->iOffset);
- }
+ sqlite3_result_int64(ctx, pCsr->iOffset);
break;
case 9: /* pgsize */
sqlite3_result_int(ctx, pCsr->szPage);
break;
- case 10: { /* schema */
+ default: { /* schema */
sqlite3 *db = sqlite3_context_db_handle(ctx);
int iDb = pCsr->iDb;
sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC);
break;
}
- default: { /* aggregate */
- sqlite3_result_int(ctx, pCsr->isAgg);
- break;
- }
}
return SQLITE_OK;
}
static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
Index: src/delete.c
==================================================================
--- src/delete.c
+++ src/delete.c
@@ -423,11 +423,11 @@
sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
}
}else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
{
- u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE;
+ u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
if( HasRowid(pTab) ){
/* For a rowid table, initialize the RowSet to an empty set */
pPk = 0;
@@ -459,10 +459,13 @@
if( pWInfo==0 ) goto delete_from_cleanup;
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
+ if( sqlite3WhereUsesDeferredSeek(pWInfo) ){
+ sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur);
+ }
/* Keep track of the number of rows to be deleted */
if( memCnt ){
sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
}
@@ -493,10 +496,11 @@
memset(aToOpen, 1, nIdx+1);
aToOpen[nIdx+1] = 0;
if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
+ addrBypass = sqlite3VdbeMakeLabel(pParse);
}else{
if( pPk ){
/* Add the PK key for this row to the temporary table */
iKey = ++pParse->nMem;
nKey = 0; /* Zero tells OP_Found to use a composite key */
@@ -506,17 +510,10 @@
}else{
/* Add the rowid of the row to be deleted to the RowSet */
nKey = 1; /* OP_DeferredSeek always uses a single rowid */
sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
}
- }
-
- /* If this DELETE cannot use the ONEPASS strategy, this is the
- ** end of the WHERE loop */
- if( eOnePass!=ONEPASS_OFF ){
- addrBypass = sqlite3VdbeMakeLabel(pParse);
- }else{
sqlite3WhereEnd(pWInfo);
}
/* Unless this is a view, open cursors for the table we are
** deleting from and all its indices. If this is a view, then the
@@ -731,12 +728,11 @@
sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
for(iCol=0; iColnCol; iCol++){
testcase( mask!=0xffffffff && iCol==31 );
testcase( mask!=0xffffffff && iCol==32 );
if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){
- int kk = sqlite3TableColumnToStorage(pTab, iCol);
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+kk+1);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
}
}
/* Invoke BEFORE DELETE trigger programs. */
addrStart = sqlite3VdbeCurrentAddr(v);
@@ -912,12 +908,10 @@
*piPartIdxLabel = sqlite3VdbeMakeLabel(pParse);
pParse->iSelfTab = iDataCur + 1;
sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
SQLITE_JUMPIFNULL);
pParse->iSelfTab = 0;
- pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02;
- ** pPartIdxWhere may have corrupted regPrior registers */
}else{
*piPartIdxLabel = 0;
}
}
nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
Index: src/expr.c
==================================================================
--- src/expr.c
+++ src/expr.c
@@ -42,15 +42,12 @@
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
char sqlite3ExprAffinity(Expr *pExpr){
int op;
- while( ExprHasProperty(pExpr, EP_Skip) ){
- assert( pExpr->op==TK_COLLATE );
- pExpr = pExpr->pLeft;
- assert( pExpr!=0 );
- }
+ pExpr = sqlite3ExprSkipCollate(pExpr);
+ if( pExpr->flags & EP_Generic ) return 0;
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
}
@@ -68,14 +65,11 @@
assert( pExpr->pLeft->flags&EP_xIsSelect );
return sqlite3ExprAffinity(
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
);
}
- if( op==TK_VECTOR ){
- return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
- }
- return pExpr->affExpr;
+ return pExpr->affinity;
}
/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken. Return a pointer to a new Expr node that
@@ -106,27 +100,15 @@
sqlite3TokenInit(&s, (char*)zC);
return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}
/*
-** Skip over any TK_COLLATE operators.
+** Skip over any TK_COLLATE operators and any unlikely()
+** or likelihood() function at the root of an expression.
*/
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
- assert( pExpr->op==TK_COLLATE );
- pExpr = pExpr->pLeft;
- }
- return pExpr;
-}
-
-/*
-** Skip over any TK_COLLATE operators and/or any unlikely()
-** or likelihood() or likely() functions at the root of an
-** expression.
-*/
-Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
- while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
@@ -156,10 +138,11 @@
sqlite3 *db = pParse->db;
CollSeq *pColl = 0;
Expr *p = pExpr;
while( p ){
int op = p->op;
+ if( p->flags & EP_Generic ) break;
if( op==TK_REGISTER ) op = p->op2;
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
&& p->y.pTab!=0
){
/* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
@@ -173,14 +156,10 @@
}
if( op==TK_CAST || op==TK_UPLUS ){
p = p->pLeft;
continue;
}
- if( op==TK_VECTOR ){
- p = p->x.pList->a[0].pExpr;
- continue;
- }
if( op==TK_COLLATE ){
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
}
if( p->flags & EP_Collate ){
@@ -188,16 +167,16 @@
p = p->pLeft;
}else{
Expr *pNext = p->pRight;
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( p->x.pList==0 || p->pRight==0 );
- if( p->x.pList!=0
- && !db->mallocFailed
- && ALWAYS(!ExprHasProperty(p, EP_xIsSelect))
- ){
+ /* p->flags holds EP_Collate and p->pLeft->flags does not. And
+ ** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at
+ ** least one EP_Collate. Thus the following two ALWAYS. */
+ if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
int i;
- for(i=0; ix.pList->nExpr; i++){
+ for(i=0; ALWAYS(ix.pList->nExpr); i++){
if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
pNext = p->x.pList->a[i].pExpr;
break;
}
}
@@ -245,23 +224,28 @@
** type affinity of the other operand. This routine returns the
** type affinity that should be used for the comparison operator.
*/
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
char aff1 = sqlite3ExprAffinity(pExpr);
- if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
+ if( aff1 && aff2 ){
/* Both sides of the comparison are columns. If one has numeric
** affinity, use that. Otherwise use no affinity.
*/
if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
return SQLITE_AFF_NUMERIC;
}else{
return SQLITE_AFF_BLOB;
}
+ }else if( !aff1 && !aff2 ){
+ /* Neither side of the comparison is a column. Compare the
+ ** results directly.
+ */
+ return SQLITE_AFF_BLOB;
}else{
/* One side is a column, the other is not. Use the columns affinity. */
- assert( aff1<=SQLITE_AFF_NONE || aff2<=SQLITE_AFF_NONE );
- return (aff1<=SQLITE_AFF_NONE ? aff2 : aff1) | SQLITE_AFF_NONE;
+ assert( aff1==0 || aff2==0 );
+ return (aff1 + aff2);
}
}
/*
** pExpr is a comparison operator. Return the type affinity that should
@@ -290,17 +274,18 @@
** if the index with affinity idx_affinity may be used to implement
** the comparison in pExpr.
*/
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
char aff = comparisonAffinity(pExpr);
- if( affpRight, p->pLeft);
- }else{
- return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight);
- }
-}
-
/*
** Generate code for a comparison operator.
*/
static int codeCompare(
Parse *pParse, /* The parsing (and code generating) context */
@@ -367,23 +336,17 @@
Expr *pLeft, /* The left operand */
Expr *pRight, /* The right operand */
int opcode, /* The comparison opcode */
int in1, int in2, /* Register holding operands */
int dest, /* Jump here if true. */
- int jumpIfNull, /* If true, jump if either operand is NULL */
- int isCommuted /* The comparison has been commuted */
+ int jumpIfNull /* If true, jump if either operand is NULL */
){
int p5;
int addr;
CollSeq *p4;
- if( pParse->nErr ) return 0;
- if( isCommuted ){
- p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft);
- }else{
- p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
- }
+ p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
(void*)p4, P4_COLLSEQ);
sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5);
return addr;
@@ -590,13 +553,11 @@
int i;
int regLeft = 0;
int regRight = 0;
u8 opx = op;
int addrDone = sqlite3VdbeMakeLabel(pParse);
- int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
- if( pParse->nErr ) return;
if( nLeft!=sqlite3ExprVectorSize(pRight) ){
sqlite3ErrorMsg(pParse, "row value misused");
return;
}
assert( pExpr->op==TK_EQ || pExpr->op==TK_NE
@@ -621,11 +582,11 @@
Expr *pL, *pR;
int r1, r2;
assert( i>=0 && iop = (u8)op;
pNew->iAgg = -1;
if( pToken ){
if( nExtra==0 ){
- pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
+ pNew->flags |= EP_IntValue|EP_Leaf;
pNew->u.iValue = iValue;
}else{
pNew->u.zToken = (char*)&pNew[1];
assert( pToken->z!=0 || pToken->n==0 );
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
@@ -887,20 +848,24 @@
int op, /* Expression opcode */
Expr *pLeft, /* Left operand */
Expr *pRight /* Right operand */
){
Expr *p;
- p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
- if( p ){
- memset(p, 0, sizeof(Expr));
- p->op = op & 0xff;
- p->iAgg = -1;
+ if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){
+ /* Take advantage of short-circuit false optimization for AND */
+ p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
+ }else{
+ p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
+ if( p ){
+ memset(p, 0, sizeof(Expr));
+ p->op = op & 0xff;
+ p->iAgg = -1;
+ }
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
+ }
+ if( p ) {
sqlite3ExprCheckHeight(pParse, p->nHeight);
- }else{
- sqlite3ExprDelete(pParse->db, pLeft);
- sqlite3ExprDelete(pParse->db, pRight);
}
return p;
}
/*
@@ -916,33 +881,59 @@
assert( pParse->db->mallocFailed );
sqlite3SelectDelete(pParse->db, pSelect);
}
}
+
+/*
+** If the expression is always either TRUE or FALSE (respectively),
+** then return 1. If one cannot determine the truth value of the
+** expression at compile-time return 0.
+**
+** This is an optimization. If is OK to return 0 here even if
+** the expression really is always false or false (a false negative).
+** But it is a bug to return 1 if the expression might have different
+** boolean values in different circumstances (a false positive.)
+**
+** Note that if the expression is part of conditional for a
+** LEFT JOIN, then we cannot determine at compile-time whether or not
+** is it true or false, so always return 0.
+*/
+static int exprAlwaysTrue(Expr *p){
+ int v = 0;
+ if( ExprHasProperty(p, EP_FromJoin) ) return 0;
+ if( !sqlite3ExprIsInteger(p, &v) ) return 0;
+ return v!=0;
+}
+static int exprAlwaysFalse(Expr *p){
+ int v = 0;
+ if( ExprHasProperty(p, EP_FromJoin) ) return 0;
+ if( !sqlite3ExprIsInteger(p, &v) ) return 0;
+ return v==0;
+}
/*
** Join two expressions using an AND operator. If either expression is
** NULL, then just return the other expression.
**
** If one side or the other of the AND is known to be false, then instead
** of returning an AND expression, just return a constant expression with
** a value of false.
*/
-Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
- sqlite3 *db = pParse->db;
- if( pLeft==0 ){
+Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
+ if( pLeft==0 ){
return pRight;
}else if( pRight==0 ){
return pLeft;
- }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight))
- && !IN_RENAME_OBJECT
- ){
+ }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
sqlite3ExprDelete(db, pLeft);
sqlite3ExprDelete(db, pRight);
- return sqlite3Expr(db, TK_INTEGER, "0");
+ return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
}else{
- return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
+ Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
+ sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
+ return pNew;
}
}
/*
** Construct a new expression node for a function with multiple
@@ -971,44 +962,10 @@
sqlite3ExprSetHeightAndFlags(pParse, pNew);
if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
return pNew;
}
-/*
-** Check to see if a function is usable according to current access
-** rules:
-**
-** SQLITE_FUNC_DIRECT - Only usable from top-level SQL
-**
-** SQLITE_FUNC_UNSAFE - Usable if TRUSTED_SCHEMA or from
-** top-level SQL
-**
-** If the function is not usable, create an error.
-*/
-void sqlite3ExprFunctionUsable(
- Parse *pParse, /* Parsing and code generating context */
- Expr *pExpr, /* The function invocation */
- FuncDef *pDef /* The function being invoked */
-){
- assert( !IN_RENAME_OBJECT );
- assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 );
- if( ExprHasProperty(pExpr, EP_FromDDL) ){
- if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
- || (pParse->db->flags & SQLITE_TrustedSchema)==0
- ){
- /* Functions prohibited in triggers and views if:
- ** (1) tagged with SQLITE_DIRECTONLY
- ** (2) not tagged with SQLITE_INNOCUOUS (which means it
- ** is tagged with SQLITE_FUNC_UNSAFE) and
- ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
- ** that the schema is possibly tainted).
- */
- sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
- }
- }
-}
-
/*
** Assign a variable number to an expression that encodes a wildcard
** in the original SQL statement.
**
** Wildcards consisting of a single "?" are assigned the next sequential
@@ -1109,22 +1066,19 @@
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( p->x.pList==0 || p->pRight==0 );
if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
if( p->pRight ){
- assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3ExprDeleteNN(db, p->pRight);
}else if( ExprHasProperty(p, EP_xIsSelect) ){
- assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3SelectDelete(db, p->x.pSelect);
}else{
sqlite3ExprListDelete(db, p->x.pList);
-#ifndef SQLITE_OMIT_WINDOWFUNC
- if( ExprHasProperty(p, EP_WinFunc) ){
- sqlite3WindowDelete(db, p->y.pWin);
- }
-#endif
+ }
+ if( ExprHasProperty(p, EP_WinFunc) ){
+ assert( p->op==TK_FUNCTION );
+ sqlite3WindowDelete(db, p->y.pWin);
}
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
sqlite3DbFreeNN(db, p);
@@ -1132,22 +1086,10 @@
}
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
-/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
-** expression.
-*/
-void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
- if( p ){
- if( IN_RENAME_OBJECT ){
- sqlite3RenameExprUnmap(pParse, p);
- }
- sqlite3ExprDeleteNN(pParse->db, p);
- }
-}
-
/*
** Return the number of bytes allocated for the expression structure
** passed as the first argument. This is always one of EXPR_FULLSIZE,
** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
*/
@@ -1154,10 +1096,20 @@
static int exprStructSize(Expr *p){
if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
return EXPR_FULLSIZE;
}
+
+/*
+** Copy the complete content of an Expr node, taking care not to read
+** past the end of the structure for a reduced-size version of the source
+** Expr.
+*/
+static void exprNodeCopy(Expr *pDest, Expr *pSrc){
+ memset(pDest, 0, sizeof(Expr));
+ memcpy(pDest, pSrc, exprStructSize(pSrc));
+}
/*
** The dupedExpr*Size() routines each return the number of bytes required
** to store a copy of an expression or expression tree. They differ in
** how much of the tree is measured.
@@ -1394,17 +1346,14 @@
** gatherSelectWindowsCallback() are used to scan all the expressions
** an a newly duplicated SELECT statement and gather all of the Window
** objects found there, assembling them onto the linked list at Select->pWin.
*/
static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){
- if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_WinFunc) ){
- Select *pSelect = pWalker->u.pSelect;
- Window *pWin = pExpr->y.pWin;
- assert( pWin );
- assert( IsWindowFunc(pExpr) );
- assert( pWin->ppThis==0 );
- sqlite3WindowLink(pSelect, pWin);
+ if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){
+ assert( ExprHasProperty(pExpr, EP_WinFunc) );
+ pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin;
+ pWalker->u.pSelect->pWin = pExpr->y.pWin;
}
return WRC_Continue;
}
static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){
return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune;
@@ -1472,15 +1421,15 @@
assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 );
assert( pPriorSelectCol==pItem[-1].pExpr->pLeft );
pNewExpr->pLeft = pPriorSelectCol;
}
}
- pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
- pItem->sortFlags = pOldItem->sortFlags;
- pItem->eEName = pOldItem->eEName;
+ pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
+ pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
+ pItem->sortOrder = pOldItem->sortOrder;
pItem->done = 0;
- pItem->bNulls = pOldItem->bNulls;
+ pItem->bSpanIsTab = pOldItem->bSpanIsTab;
pItem->bSorterRef = pOldItem->bSorterRef;
pItem->u = pOldItem->u;
}
return pNew;
}
@@ -1586,11 +1535,11 @@
pNew->nSelectRow = p->nSelectRow;
pNew->pWith = withDup(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
- if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew);
+ if( p->pWin ) gatherSelectWindows(pNew);
#endif
pNew->selId = p->selId;
*pp = pNew;
pp = &pNew->pPrior;
pNext = pNew;
@@ -1643,13 +1592,13 @@
goto no_mem;
}
pList = pNew;
}
pItem = &pList->a[pList->nExpr++];
- assert( offsetof(struct ExprList_item,zEName)==sizeof(pItem->pExpr) );
+ assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) );
assert( offsetof(struct ExprList_item,pExpr)==0 );
- memset(&pItem->zEName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zEName));
+ memset(&pItem->zName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zName));
pItem->pExpr = pExpr;
return pList;
no_mem:
/* Avoid leaking memory if malloc has failed. */
@@ -1695,18 +1644,14 @@
goto vector_append_error;
}
for(i=0; inId; i++){
Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i);
- assert( pSubExpr!=0 || db->mallocFailed );
- assert( pSubExpr==0 || pSubExpr->iTable==0 );
- if( pSubExpr==0 ) continue;
- pSubExpr->iTable = pColumns->nId;
pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
if( pList ){
assert( pList->nExpr==iFirst+i+1 );
- pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName;
+ pList->a[pList->nExpr-1].zName = pColumns->a[i].zName;
pColumns->a[i].zName = 0;
}
}
if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
@@ -1723,50 +1668,34 @@
** the RHS and LHS sizes match during code generation. */
pFirst->iTable = pColumns->nId;
}
vector_append_error:
- sqlite3ExprUnmapAndDelete(pParse, pExpr);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameExprUnmap(pParse, pExpr);
+ }
+ sqlite3ExprDelete(db, pExpr);
sqlite3IdListDelete(db, pColumns);
return pList;
}
/*
** Set the sort order for the last element on the given ExprList.
*/
-void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){
- struct ExprList_item *pItem;
+void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
if( p==0 ) return;
+ assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
assert( p->nExpr>0 );
-
- assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 );
- assert( iSortOrder==SQLITE_SO_UNDEFINED
- || iSortOrder==SQLITE_SO_ASC
- || iSortOrder==SQLITE_SO_DESC
- );
- assert( eNulls==SQLITE_SO_UNDEFINED
- || eNulls==SQLITE_SO_ASC
- || eNulls==SQLITE_SO_DESC
- );
-
- pItem = &p->a[p->nExpr-1];
- assert( pItem->bNulls==0 );
- if( iSortOrder==SQLITE_SO_UNDEFINED ){
- iSortOrder = SQLITE_SO_ASC;
- }
- pItem->sortFlags = (u8)iSortOrder;
-
- if( eNulls!=SQLITE_SO_UNDEFINED ){
- pItem->bNulls = 1;
- if( iSortOrder!=eNulls ){
- pItem->sortFlags |= KEYINFO_ORDER_BIGNULL;
- }
- }
+ if( iSortOrder<0 ){
+ assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
+ return;
+ }
+ p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
}
/*
-** Set the ExprList.a[].zEName element of the most recently added item
+** Set the ExprList.a[].zName element of the most recently added item
** on the expression list.
**
** pList might be NULL following an OOM error. But pName should never be
** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
** is set.
@@ -1780,16 +1709,15 @@
assert( pList!=0 || pParse->db->mallocFailed!=0 );
if( pList ){
struct ExprList_item *pItem;
assert( pList->nExpr>0 );
pItem = &pList->a[pList->nExpr-1];
- assert( pItem->zEName==0 );
- assert( pItem->eEName==ENAME_NAME );
- pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
- if( dequote ) sqlite3Dequote(pItem->zEName);
+ assert( pItem->zName==0 );
+ pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
+ if( dequote ) sqlite3Dequote(pItem->zName);
if( IN_RENAME_OBJECT ){
- sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
+ sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName);
}
}
}
/*
@@ -1809,14 +1737,12 @@
sqlite3 *db = pParse->db;
assert( pList!=0 || db->mallocFailed!=0 );
if( pList ){
struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
assert( pList->nExpr>0 );
- if( pItem->zEName==0 ){
- pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd);
- pItem->eEName = ENAME_SPAN;
- }
+ sqlite3DbFree(db, pItem->zSpan);
+ pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd);
}
}
/*
** If the expression list pEList contains more than iLimit elements,
@@ -1842,11 +1768,12 @@
int i = pList->nExpr;
struct ExprList_item *pItem = pList->a;
assert( pList->nExpr>0 );
do{
sqlite3ExprDelete(db, pItem->pExpr);
- sqlite3DbFree(db, pItem->zEName);
+ sqlite3DbFree(db, pItem->zName);
+ sqlite3DbFree(db, pItem->zSpan);
pItem++;
}while( --i>0 );
sqlite3DbFreeNN(db, pList);
}
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
@@ -1879,39 +1806,23 @@
int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
UNUSED_PARAMETER(NotUsed);
pWalker->eCode = 0;
return WRC_Abort;
}
-
-/*
-** Check the input string to see if it is "true" or "false" (in any case).
-**
-** If the string is.... Return
-** "true" EP_IsTrue
-** "false" EP_IsFalse
-** anything else 0
-*/
-u32 sqlite3IsTrueOrFalse(const char *zIn){
- if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue;
- if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse;
- return 0;
-}
-
/*
** If the input expression is an ID with the name "true" or "false"
** then convert it into an TK_TRUEFALSE term. Return non-zero if
** the conversion happened, and zero if the expression is unaltered.
*/
int sqlite3ExprIdToTrueFalse(Expr *pExpr){
- u32 v;
assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
if( !ExprHasProperty(pExpr, EP_Quoted)
- && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0
+ && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
+ || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
){
pExpr->op = TK_TRUEFALSE;
- ExprSetProperty(pExpr, v);
return 1;
}
return 0;
}
@@ -1918,44 +1829,16 @@
/*
** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE
** and 0 if it is FALSE.
*/
int sqlite3ExprTruthValue(const Expr *pExpr){
- pExpr = sqlite3ExprSkipCollate((Expr*)pExpr);
assert( pExpr->op==TK_TRUEFALSE );
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
return pExpr->u.zToken[4]==0;
}
-/*
-** If pExpr is an AND or OR expression, try to simplify it by eliminating
-** terms that are always true or false. Return the simplified expression.
-** Or return the original expression if no simplification is possible.
-**
-** Examples:
-**
-** (x<10) AND true => (x<10)
-** (x<10) AND false => false
-** (x<10) AND (y=22 OR false) => (x<10) AND (y=22)
-** (x<10) AND (y=22 OR true) => (x<10)
-** (y=22) OR true => true
-*/
-Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
- assert( pExpr!=0 );
- if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
- Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
- Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
- if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
- pExpr = pExpr->op==TK_AND ? pRight : pLeft;
- }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
- pExpr = pExpr->op==TK_AND ? pLeft : pRight;
- }
- }
- return pExpr;
-}
-
/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant. The
** Walker.eCode value determines the type of "constant" we are looking
@@ -1969,15 +1852,14 @@
** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5
**
** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
** is found to not be a constant.
**
-** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT
-** expressions in a CREATE TABLE statement. The Walker.eCode value is 5
-** when parsing an existing schema out of the sqlite_master table and 4
-** when processing a new CREATE TABLE statement. A bound parameter raises
-** an error for new statements, but is silently converted
+** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
+** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing
+** an existing schema and 4 when processing a new statement. A bound
+** parameter raises an error for new statements, but is silently converted
** to NULL for existing schemas. This allows sqlite_master tables that
** contain a bound parameter because they were generated by older versions
** of SQLite to be parsed by newer versions of SQLite without raising a
** malformed schema error.
*/
@@ -1994,14 +1876,11 @@
switch( pExpr->op ){
/* Consider functions to be constant if all their arguments are constant
** and either pWalker->eCode==4 or 5 or the function has the
** SQLITE_FUNC_CONST flag. */
case TK_FUNCTION:
- if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc))
- && !ExprHasProperty(pExpr, EP_WinFunc)
- ){
- if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL);
+ if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
return WRC_Continue;
}else{
pWalker->eCode = 0;
return WRC_Abort;
}
@@ -2161,25 +2040,13 @@
sqlite3WalkExpr(&w, p);
return w.eCode;
}
/*
-** Walk an expression tree for the DEFAULT field of a column definition
-** in a CREATE TABLE statement. Return non-zero if the expression is
-** acceptable for use as a DEFAULT. That is to say, return non-zero if
-** the expression is constant or a function call with constant arguments.
-** Return and 0 if there are any variables.
-**
-** isInit is true when parsing from sqlite_master. isInit is false when
-** processing a new CREATE TABLE statement. When isInit is true, parameters
-** (such as ? or $abc) in the expression are converted into NULL. When
-** isInit is false, parameters raise an error. Parameters should not be
-** allowed in a CREATE TABLE statement, but some legacy versions of SQLite
-** allowed it, so we need to support it when reading sqlite_master for
-** backwards compatibility.
-**
-** If isInit is true, set EP_FromDDL on every TK_FUNCTION node.
+** Walk an expression tree. Return non-zero if the expression is constant
+** or a function call with constant arguments. Return and 0 if there
+** are any variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
@@ -2212,11 +2079,11 @@
** in *pValue. If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
- if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */
+ if( p==0 ) return 0; /* Can only happen following on OOM */
/* If an expression is an integer literal that fits in a signed 32-bit
** integer, then the EP_IntValue flag will have already been set */
assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
|| sqlite3GetInt32(p->u.zToken, &rc)==0 );
@@ -2272,13 +2139,11 @@
case TK_BLOB:
return 0;
case TK_COLUMN:
return ExprHasProperty(p, EP_CanBeNull) ||
p->y.pTab==0 || /* Reference to column of index on expression */
- (p->iColumn>=0
- && ALWAYS(p->y.pTab->aCol!=0) /* Defense against OOM problems */
- && p->y.pTab->aCol[p->iColumn].notNull==0);
+ (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
default:
return 1;
}
}
@@ -2292,34 +2157,31 @@
** is harmless. A false positive, however, can result in the wrong
** answer.
*/
int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
u8 op;
- int unaryMinus = 0;
if( aff==SQLITE_AFF_BLOB ) return 1;
- while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
- if( p->op==TK_UMINUS ) unaryMinus = 1;
- p = p->pLeft;
- }
+ while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
switch( op ){
case TK_INTEGER: {
- return aff>=SQLITE_AFF_NUMERIC;
+ return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC;
}
case TK_FLOAT: {
- return aff>=SQLITE_AFF_NUMERIC;
+ return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC;
}
case TK_STRING: {
- return !unaryMinus && aff==SQLITE_AFF_TEXT;
+ return aff==SQLITE_AFF_TEXT;
}
case TK_BLOB: {
- return !unaryMinus;
+ return 1;
}
case TK_COLUMN: {
assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */
- return aff>=SQLITE_AFF_NUMERIC && p->iColumn<0;
+ return p->iColumn<0
+ && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC);
}
default: {
return 0;
}
}
@@ -2498,11 +2360,11 @@
** then aiMap[] is populated with {2, 0, 1}.
*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3FindInIndex(
Parse *pParse, /* Parsing context */
- Expr *pX, /* The IN expression */
+ Expr *pX, /* The right-hand side (RHS) of the IN operator */
u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
int *prRhsHasNull, /* Register holding NULL status. See notes */
int *aiMap, /* Mapping from Index fields to RHS fields */
int *piTab /* OUT: index to use */
){
@@ -2751,14 +2613,12 @@
** message of the form:
**
** "sub-select returns N columns - expected M"
*/
void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
- if( pParse->nErr==0 ){
- const char *zFmt = "sub-select returns %d columns - expected %d";
- sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
- }
+ const char *zFmt = "sub-select returns %d columns - expected %d";
+ sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
}
#endif
/*
** Expression pExpr is a vector that has been used in a context where
@@ -2925,13 +2785,13 @@
*/
char affinity; /* Affinity of the LHS of the IN */
int i;
ExprList *pList = pExpr->x.pList;
struct ExprList_item *pItem;
- int r1, r2;
+ int r1, r2, r3;
affinity = sqlite3ExprAffinity(pLeft);
- if( affinity<=SQLITE_AFF_NONE ){
+ if( !affinity ){
affinity = SQLITE_AFF_BLOB;
}
if( pKeyInfo ){
assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
@@ -2948,18 +2808,17 @@
** this code only executes once. Because for a non-constant
** expression we need to rerun this code each time.
*/
if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
sqlite3VdbeChangeToNoop(v, addrOnce);
- ExprClearProperty(pExpr, EP_Subrtn);
addrOnce = 0;
}
/* Evaluate the expression and insert it into the temp table */
- sqlite3ExprCode(pParse, pE2, r1);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1);
+ r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
}
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempReg(pParse, r2);
}
if( pKeyInfo ){
@@ -2968,11 +2827,10 @@
if( addrOnce ){
sqlite3VdbeJumpHere(v, addrOnce);
/* Subroutine return */
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
- sqlite3ClearTempRegCache(pParse);
}
}
#endif /* SQLITE_OMIT_SUBQUERY */
/*
@@ -2982,11 +2840,11 @@
** (SELECT a FROM b) -- subquery
** EXISTS (SELECT a FROM b) -- EXISTS subquery
**
** The pExpr parameter is the SELECT or EXISTS operator to be coded.
**
-** Return the register that holds the result. For a multi-column SELECT,
+** The register that holds the result. For a multi-column SELECT,
** the result is stored in a contiguous array of registers and the
** return value is the register of the left-most result column.
** Return 0 if an error occurs.
*/
#ifndef SQLITE_OMIT_SUBQUERY
@@ -3060,25 +2918,15 @@
}else{
dest.eDest = SRT_Exists;
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
+ pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
if( pSel->pLimit ){
- /* The subquery already has a limit. If the pre-existing limit is X
- ** then make the new limit X<>0 so that the new limit is either 1 or 0 */
- sqlite3 *db = pParse->db;
- pLimit = sqlite3Expr(db, TK_INTEGER, "0");
- if( pLimit ){
- pLimit->affExpr = SQLITE_AFF_NUMERIC;
- pLimit = sqlite3PExpr(pParse, TK_NE,
- sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit);
- }
- sqlite3ExprDelete(db, pSel->pLimit->pLeft);
+ sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
pSel->pLimit->pLeft = pLimit;
}else{
- /* If there is no pre-existing limit add a limit of 1 */
- pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
}
pSel->iLimit = 0;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
@@ -3089,11 +2937,10 @@
sqlite3VdbeJumpHere(v, addrOnce);
/* Subroutine return */
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
- sqlite3ClearTempRegCache(pParse);
}
return rReg;
}
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -3237,47 +3084,33 @@
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
int labelOk = sqlite3VdbeMakeLabel(pParse);
int r2, regToFree;
int regCkNull = 0;
int ii;
- int bLhsReal; /* True if the LHS of the IN has REAL affinity */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( destIfNull!=destIfFalse ){
regCkNull = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
}
- bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL;
for(ii=0; iinExpr; ii++){
- if( bLhsReal ){
- r2 = regToFree = sqlite3GetTempReg(pParse);
- sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2);
- sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC);
- }else{
- r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
- }
+ r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
}
- sqlite3ReleaseTempReg(pParse, regToFree);
if( iinExpr-1 || destIfNull!=destIfFalse ){
- int op = rLhs!=r2 ? OP_Eq : OP_NotNull;
- sqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2,
+ sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2,
(void*)pColl, P4_COLLSEQ);
- VdbeCoverageIf(v, iinExpr-1 && op==OP_Eq);
- VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq);
- VdbeCoverageIf(v, iinExpr-1 && op==OP_NotNull);
- VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull);
+ VdbeCoverageIf(v, iinExpr-1);
+ VdbeCoverageIf(v, ii==pList->nExpr-1);
sqlite3VdbeChangeP5(v, zAff[0]);
}else{
- int op = rLhs!=r2 ? OP_Ne : OP_IsNull;
assert( destIfNull==destIfFalse );
- sqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2,
- (void*)pColl, P4_COLLSEQ);
- VdbeCoverageIf(v, op==OP_Ne);
- VdbeCoverageIf(v, op==OP_IsNull);
+ sqlite3VdbeAddOp4(v, OP_Ne, rLhs, destIfFalse, r2,
+ (void*)pColl, P4_COLLSEQ); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL);
}
+ sqlite3ReleaseTempReg(pParse, regToFree);
}
if( regCkNull ){
sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
sqlite3VdbeGoto(v, destIfFalse);
}
@@ -3293,11 +3126,10 @@
if( destIfNull==destIfFalse ){
destStep2 = destIfFalse;
}else{
destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
}
- if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
for(i=0; ipLeft, i);
if( sqlite3ExprCanBeNull(p) ){
sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
VdbeCoverage(v);
@@ -3475,86 +3307,35 @@
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
iTabCol, regOut);
}
}
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
-/*
-** Generate code that will compute the value of generated column pCol
-** and store the result in register regOut
-*/
-void sqlite3ExprCodeGeneratedColumn(
- Parse *pParse,
- Column *pCol,
- int regOut
-){
- int iAddr;
- Vdbe *v = pParse->pVdbe;
- assert( v!=0 );
- assert( pParse->iSelfTab!=0 );
- if( pParse->iSelfTab>0 ){
- iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut);
- }else{
- iAddr = 0;
- }
- sqlite3ExprCode(pParse, pCol->pDflt, regOut);
- if( pCol->affinity>=SQLITE_AFF_TEXT ){
- sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
- }
- if( iAddr ) sqlite3VdbeJumpHere(v, iAddr);
-}
-#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
-
/*
** Generate code to extract the value of the iCol-th column of a table.
*/
void sqlite3ExprCodeGetColumnOfTable(
- Vdbe *v, /* Parsing context */
+ Vdbe *v, /* The VDBE under construction */
Table *pTab, /* The table containing the value */
int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */
int iCol, /* Index of the column to extract */
int regOut /* Extract the value into this register */
){
- Column *pCol;
- assert( v!=0 );
if( pTab==0 ){
sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
return;
}
if( iCol<0 || iCol==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
}else{
- int op;
- int x;
- if( IsVirtual(pTab) ){
- op = OP_VColumn;
- x = iCol;
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){
- Parse *pParse = sqlite3VdbeParser(v);
- if( pCol->colFlags & COLFLAG_BUSY ){
- sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName);
- }else{
- int savedSelfTab = pParse->iSelfTab;
- pCol->colFlags |= COLFLAG_BUSY;
- pParse->iSelfTab = iTabCur+1;
- sqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut);
- pParse->iSelfTab = savedSelfTab;
- pCol->colFlags &= ~COLFLAG_BUSY;
- }
- return;
-#endif
- }else if( !HasRowid(pTab) ){
- testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) );
- x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
- op = OP_Column;
- }else{
- x = sqlite3TableColumnToStorage(pTab,iCol);
- testcase( x!=iCol );
- op = OP_Column;
+ int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
+ int x = iCol;
+ if( !HasRowid(pTab) && !IsVirtual(pTab) ){
+ x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
}
sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
+ }
+ if( iCol>=0 ){
sqlite3ColumnDefault(v, pTab, iCol, regOut);
}
}
/*
@@ -3570,34 +3351,34 @@
int iColumn, /* Index of the table column */
int iTable, /* The cursor pointing to the table */
int iReg, /* Store results here */
u8 p5 /* P5 value for OP_Column + FLAGS */
){
- assert( pParse->pVdbe!=0 );
- sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg);
+ Vdbe *v = pParse->pVdbe;
+ assert( v!=0 );
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
if( p5 ){
- VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
- if( pOp->opcode==OP_Column ) pOp->p5 = p5;
+ sqlite3VdbeChangeP5(v, p5);
}
return iReg;
}
/*
** Generate code to move content from registers iFrom...iFrom+nReg-1
** over to iTo..iTo+nReg-1.
*/
void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
+ assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
}
/*
** Convert a scalar expression node to a TK_REGISTER referencing
** register iReg. The caller must ensure that iReg already contains
** the correct value for the expression.
*/
-static void exprToRegister(Expr *pExpr, int iReg){
- Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
+static void exprToRegister(Expr *p, int iReg){
p->op2 = p->op;
p->op = TK_REGISTER;
p->iTable = iReg;
ExprClearProperty(p, EP_Skip);
}
@@ -3635,113 +3416,10 @@
}
}
return iResult;
}
-/*
-** Generate code to implement special SQL functions that are implemented
-** in-line rather than by using the usual callbacks.
-*/
-static int exprCodeInlineFunction(
- Parse *pParse, /* Parsing context */
- ExprList *pFarg, /* List of function arguments */
- int iFuncId, /* Function ID. One of the INTFUNC_... values */
- int target /* Store function result in this register */
-){
- int nFarg;
- Vdbe *v = pParse->pVdbe;
- assert( v!=0 );
- assert( pFarg!=0 );
- nFarg = pFarg->nExpr;
- assert( nFarg>0 ); /* All in-line functions have at least one argument */
- switch( iFuncId ){
- case INLINEFUNC_coalesce: {
- /* Attempt a direct implementation of the built-in COALESCE() and
- ** IFNULL() functions. This avoids unnecessary evaluation of
- ** arguments past the first non-NULL argument.
- */
- int endCoalesce = sqlite3VdbeMakeLabel(pParse);
- int i;
- assert( nFarg>=2 );
- sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
- for(i=1; ia[i].pExpr, target);
- }
- if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){
- sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */
- }
- sqlite3VdbeResolveLabel(v, endCoalesce);
- break;
- }
-
- default: {
- /* The UNLIKELY() function is a no-op. The result is the value
- ** of the first argument.
- */
- assert( nFarg==1 || nFarg==2 );
- target = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
- break;
- }
-
- /***********************************************************************
- ** Test-only SQL functions that are only usable if enabled
- ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
- */
- case INLINEFUNC_expr_compare: {
- /* Compare two expressions using sqlite3ExprCompare() */
- assert( nFarg==2 );
- sqlite3VdbeAddOp2(v, OP_Integer,
- sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
- target);
- break;
- }
-
- case INLINEFUNC_expr_implies_expr: {
- /* Compare two expressions using sqlite3ExprImpliesExpr() */
- assert( nFarg==2 );
- sqlite3VdbeAddOp2(v, OP_Integer,
- sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
- target);
- break;
- }
-
- case INLINEFUNC_implies_nonnull_row: {
- /* REsult of sqlite3ExprImpliesNonNullRow() */
- Expr *pA1;
- assert( nFarg==2 );
- pA1 = pFarg->a[1].pExpr;
- if( pA1->op==TK_COLUMN ){
- sqlite3VdbeAddOp2(v, OP_Integer,
- sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable),
- target);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- }
- break;
- }
-
-#ifdef SQLITE_DEBUG
- case INLINEFUNC_affinity: {
- /* The AFFINITY() function evaluates to a string that describes
- ** the type affinity of the argument. This is used for testing of
- ** the SQLite type logic.
- */
- const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
- char aff;
- assert( nFarg==1 );
- aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
- sqlite3VdbeLoadString(v, target,
- (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
- break;
- }
-#endif
- }
- return target;
-}
-
/*
** Generate code into the current Vdbe to evaluate the given
** expression. Attempt to store the results in register "target".
** Return the register where results are stored.
@@ -3788,26 +3466,20 @@
}
/* Otherwise, fall thru into the TK_COLUMN case */
}
case TK_COLUMN: {
int iTab = pExpr->iTable;
- int iReg;
if( ExprHasProperty(pExpr, EP_FixedCol) ){
/* This COLUMN expression is really a constant due to WHERE clause
** constraints, and that constant is coded by the pExpr->pLeft
** expresssion. However, make sure the constant has the correct
** datatype by applying the Affinity of the table column to the
** constant.
*/
- int aff;
- iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
- if( pExpr->y.pTab ){
- aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
- }else{
- aff = pExpr->affExpr;
- }
- if( aff>SQLITE_AFF_BLOB ){
+ int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
+ int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+ if( aff!=SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' );
assert( SQLITE_AFF_TEXT=='B' );
if( iReg!=target ){
sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
@@ -3818,64 +3490,21 @@
}
return iReg;
}
if( iTab<0 ){
if( pParse->iSelfTab<0 ){
- /* Other columns in the same row for CHECK constraints or
- ** generated columns or for inserting into partial index.
- ** The row is unpacked into registers beginning at
- ** 0-(pParse->iSelfTab). The rowid (if any) is in a register
- ** immediately prior to the first column.
- */
- Column *pCol;
- Table *pTab = pExpr->y.pTab;
- int iSrc;
- int iCol = pExpr->iColumn;
- assert( pTab!=0 );
- assert( iCol>=XN_ROWID );
- assert( iColnCol );
- if( iCol<0 ){
- return -1-pParse->iSelfTab;
- }
- pCol = pTab->aCol + iCol;
- testcase( iCol!=sqlite3TableColumnToStorage(pTab,iCol) );
- iSrc = sqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab;
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- if( pCol->colFlags & COLFLAG_GENERATED ){
- if( pCol->colFlags & COLFLAG_BUSY ){
- sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"",
- pCol->zName);
- return 0;
- }
- pCol->colFlags |= COLFLAG_BUSY;
- if( pCol->colFlags & COLFLAG_NOTAVAIL ){
- sqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc);
- }
- pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL);
- return iSrc;
- }else
-#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
- if( pCol->affinity==SQLITE_AFF_REAL ){
- sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target);
- sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
- return target;
- }else{
- return iSrc;
- }
+ /* Generating CHECK constraints or inserting into partial index */
+ return pExpr->iColumn - pParse->iSelfTab;
}else{
/* Coding an expression that is part of an index where column names
** in the index refer to the table to which the index belongs */
iTab = pParse->iSelfTab - 1;
}
}
- iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
+ return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
- if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){
- sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
- }
- return iReg;
}
case TK_INTEGER: {
codeInteger(pParse, pExpr, 0, target);
return target;
}
@@ -3893,16 +3522,11 @@
case TK_STRING: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
return target;
}
- default: {
- /* Make NULL the default case so that if a bug causes an illegal
- ** Expr node to be passed into this function, it will be handled
- ** sanely and not crash. But keep the assert() to bring the problem
- ** to the attention of the developers. */
- assert( op==TK_NULL );
+ case TK_NULL: {
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
return target;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
@@ -3925,11 +3549,11 @@
assert( pExpr->u.zToken!=0 );
assert( pExpr->u.zToken[0]!=0 );
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
- assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) );
+ assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
}
return target;
}
@@ -3965,12 +3589,11 @@
codeVectorCompare(pParse, pExpr, target, op, p5);
}else{
r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
codeCompare(pParse, pLeft, pExpr->pRight, op,
- r1, r2, inReg, SQLITE_STOREP2 | p5,
- ExprHasProperty(pExpr,EP_Commuted));
+ r1, r2, inReg, SQLITE_STOREP2 | p5);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
@@ -4118,18 +3741,51 @@
#endif
if( pDef==0 || pDef->xFinalize!=0 ){
sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
break;
}
- if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
- assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
- assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
- return exprCodeInlineFunction(pParse, pFarg,
- SQLITE_PTR_TO_INT(pDef->pUserData), target);
- }else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){
- sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
- }
+
+ /* Attempt a direct implementation of the built-in COALESCE() and
+ ** IFNULL() functions. This avoids unnecessary evaluation of
+ ** arguments past the first non-NULL argument.
+ */
+ if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
+ int endCoalesce = sqlite3VdbeMakeLabel(pParse);
+ assert( nFarg>=2 );
+ sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
+ for(i=1; ia[i].pExpr, target);
+ }
+ sqlite3VdbeResolveLabel(v, endCoalesce);
+ break;
+ }
+
+ /* The UNLIKELY() function is a no-op. The result is the value
+ ** of the first argument.
+ */
+ if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
+ assert( nFarg>=1 );
+ return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
+ }
+
+#ifdef SQLITE_DEBUG
+ /* The AFFINITY() function evaluates to a string that describes
+ ** the type affinity of the argument. This is used for testing of
+ ** the SQLite type logic.
+ */
+ if( pDef->funcFlags & SQLITE_FUNC_AFFINITY ){
+ const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
+ char aff;
+ assert( nFarg==1 );
+ aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
+ sqlite3VdbeLoadString(v, target,
+ aff ? azAff[aff-SQLITE_AFF_BLOB] : "none");
+ return target;
+ }
+#endif
for(i=0; ia[i].pExpr) ){
testcase( i==31 );
constMask |= MASKBIT32(i);
@@ -4202,19 +3858,16 @@
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
}else
#endif
{
- sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
- pDef, pExpr->op2);
- }
- if( nFarg ){
- if( constMask==0 ){
- sqlite3ReleaseTempRange(pParse, r1, nFarg);
- }else{
- sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1);
- }
+ sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
+ constMask, r1, target, (char*)pDef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, (u8)nFarg);
+ }
+ if( nFarg && constMask==0 ){
+ sqlite3ReleaseTempRange(pParse, r1, nFarg);
}
return target;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS:
@@ -4233,12 +3886,12 @@
int n;
if( pExpr->pLeft->iTable==0 ){
pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
}
assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
- if( pExpr->iTable!=0
- && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft))
+ if( pExpr->iTable
+ && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft))
){
sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
pExpr->iTable, n);
}
return pExpr->pLeft->iTable + pExpr->iColumn;
@@ -4304,32 +3957,32 @@
** p1==0 -> old.rowid p1==3 -> new.rowid
** p1==1 -> old.a p1==4 -> new.a
** p1==2 -> old.b p1==5 -> new.b
*/
Table *pTab = pExpr->y.pTab;
- int iCol = pExpr->iColumn;
- int p1 = pExpr->iTable * (pTab->nCol+1) + 1
- + sqlite3TableColumnToStorage(pTab, iCol);
+ int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
assert( pExpr->iTable==0 || pExpr->iTable==1 );
- assert( iCol>=-1 && iColnCol );
- assert( pTab->iPKey<0 || iCol!=pTab->iPKey );
+ assert( pExpr->iColumn>=-1 && pExpr->iColumnnCol );
+ assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
assert( p1>=0 && p1<(pTab->nCol*2+2) );
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
VdbeComment((v, "r[%d]=%s.%s", target,
(pExpr->iTable ? "new" : "old"),
- (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zName)
+ (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
));
#ifndef SQLITE_OMIT_FLOATING_POINT
/* If the column has REAL affinity, it may currently be stored as an
** integer. Use OP_RealAffinity to make sure it is really real.
**
** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
** floating point when extracting it from the record. */
- if( iCol>=0 && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){
+ if( pExpr->iColumn>=0
+ && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
+ ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
}
#endif
break;
}
@@ -4337,27 +3990,14 @@
case TK_VECTOR: {
sqlite3ErrorMsg(pParse, "row value misused");
break;
}
- /* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions
- ** that derive from the right-hand table of a LEFT JOIN. The
- ** Expr.iTable value is the table number for the right-hand table.
- ** The expression is only evaluated if that table is not currently
- ** on a LEFT JOIN NULL row.
- */
case TK_IF_NULL_ROW: {
int addrINR;
- u8 okConstFactor = pParse->okConstFactor;
addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
- /* Temporarily disable factoring of constant expressions, since
- ** even though expressions may appear to be constant, they are not
- ** really constant because they originate from the right-hand side
- ** of a LEFT JOIN. */
- pParse->okConstFactor = 0;
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- pParse->okConstFactor = okConstFactor;
sqlite3VdbeJumpHere(v, addrINR);
sqlite3VdbeChangeP3(v, addrINR, inReg);
break;
}
@@ -4380,41 +4020,35 @@
**
** The result of the expression is the Ri for the first matching Ei,
** or if there is no matching Ei, the ELSE term Y, or if there is
** no ELSE term, NULL.
*/
- case TK_CASE: {
+ default: assert( op==TK_CASE ); {
int endLabel; /* GOTO label for end of CASE stmt */
int nextCase; /* GOTO label for next WHEN clause */
int nExpr; /* 2x number of WHEN terms */
int i; /* Loop counter */
ExprList *pEList; /* List of WHEN terms */
struct ExprList_item *aListelem; /* Array of WHEN terms */
Expr opCompare; /* The X==Ei expression */
Expr *pX; /* The X expression */
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
- Expr *pDel = 0;
- sqlite3 *db = pParse->db;
assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
assert(pExpr->x.pList->nExpr > 0);
pEList = pExpr->x.pList;
aListelem = pEList->a;
nExpr = pEList->nExpr;
endLabel = sqlite3VdbeMakeLabel(pParse);
if( (pX = pExpr->pLeft)!=0 ){
- pDel = sqlite3ExprDup(db, pX, 0);
- if( db->mallocFailed ){
- sqlite3ExprDelete(db, pDel);
- break;
- }
+ exprNodeCopy(&tempX, pX);
testcase( pX->op==TK_COLUMN );
- exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
+ exprToRegister(&tempX, exprCodeVector(pParse, &tempX, ®Free1));
testcase( regFree1==0 );
memset(&opCompare, 0, sizeof(opCompare));
opCompare.op = TK_EQ;
- opCompare.pLeft = pDel;
+ opCompare.pLeft = &tempX;
pTest = &opCompare;
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
** The value in regFree1 might get SCopy-ed into the file result.
** So make sure that the regFree1 register is not reused for other
** purposes and possibly overwritten. */
@@ -4438,37 +4072,36 @@
if( (nExpr&1)!=0 ){
sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
- sqlite3ExprDelete(db, pDel);
sqlite3VdbeResolveLabel(v, endLabel);
break;
}
#ifndef SQLITE_OMIT_TRIGGER
case TK_RAISE: {
- assert( pExpr->affExpr==OE_Rollback
- || pExpr->affExpr==OE_Abort
- || pExpr->affExpr==OE_Fail
- || pExpr->affExpr==OE_Ignore
+ assert( pExpr->affinity==OE_Rollback
+ || pExpr->affinity==OE_Abort
+ || pExpr->affinity==OE_Fail
+ || pExpr->affinity==OE_Ignore
);
if( !pParse->pTriggerTab ){
sqlite3ErrorMsg(pParse,
"RAISE() may only be used within a trigger-program");
return 0;
}
- if( pExpr->affExpr==OE_Abort ){
+ if( pExpr->affinity==OE_Abort ){
sqlite3MayAbort(pParse);
}
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- if( pExpr->affExpr==OE_Ignore ){
+ if( pExpr->affinity==OE_Ignore ){
sqlite3VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
VdbeCoverage(v);
}else{
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
- pExpr->affExpr, pExpr->u.zToken, 0, 0);
+ pExpr->affinity, pExpr->u.zToken, 0, 0);
}
break;
}
#endif
@@ -4529,11 +4162,11 @@
** code to fill the register in the initialization section of the
** VDBE program, in order to factor it out of the evaluation loop.
*/
int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
int r2;
- pExpr = sqlite3ExprSkipCollateAndLikely(pExpr);
+ pExpr = sqlite3ExprSkipCollate(pExpr);
if( ConstFactorOk(pParse)
&& pExpr->op!=TK_REGISTER
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
*pReg = 0;
@@ -4558,20 +4191,18 @@
*/
void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
assert( target>0 && target<=pParse->nMem );
- inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
- assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
- if( inReg!=target && pParse->pVdbe ){
- u8 op;
- if( ExprHasProperty(pExpr,EP_Subquery) ){
- op = OP_Copy;
- }else{
- op = OP_SCopy;
- }
- sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target);
+ if( pExpr && pExpr->op==TK_REGISTER ){
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
+ }else{
+ inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
+ assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
+ if( inReg!=target && pParse->pVdbe ){
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
+ }
}
}
/*
** Make a transient copy of expression pExpr and then code it using
@@ -4596,10 +4227,34 @@
sqlite3ExprCodeAtInit(pParse, pExpr, target);
}else{
sqlite3ExprCode(pParse, pExpr, target);
}
}
+
+/*
+** Generate code that evaluates the given expression and puts the result
+** in register target.
+**
+** Also make a copy of the expression results into another "cache" register
+** and modify the expression so that the next time it is evaluated,
+** the result is a copy of the cache register.
+**
+** This routine is used for expressions that are used multiple
+** times. They are evaluated once and the results of the expression
+** are reused.
+*/
+void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
+ Vdbe *v = pParse->pVdbe;
+ int iMem;
+
+ assert( target>0 );
+ assert( pExpr->op!=TK_REGISTER );
+ sqlite3ExprCode(pParse, pExpr, target);
+ iMem = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
+ exprToRegister(pExpr, iMem);
+}
/*
** Generate code that pushes the value of every element of the given
** expression list into a sequence of registers beginning at target.
**
@@ -4660,11 +4315,10 @@
VdbeOp *pOp;
if( copyOp==OP_Copy
&& (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
&& pOp->p1+pOp->p3+1==inReg
&& pOp->p2+pOp->p3+1==target+i
- && pOp->p5==0 /* The do-not-merge flag must be clear */
){
pOp->p3++;
}else{
sqlite3VdbeAddOp2(v, copyOp, inReg, target+i);
}
@@ -4699,48 +4353,44 @@
Expr *pExpr, /* The BETWEEN expression */
int dest, /* Jump destination or storage location */
void (*xJump)(Parse*,Expr*,int,int), /* Action to take */
int jumpIfNull /* Take the jump if the BETWEEN is NULL */
){
- Expr exprAnd; /* The AND operator in x>=y AND x<=z */
+ Expr exprAnd; /* The AND operator in x>=y AND x<=z */
Expr compLeft; /* The x>=y term */
Expr compRight; /* The x<=z term */
+ Expr exprX; /* The x subexpression */
int regFree1 = 0; /* Temporary use register */
- Expr *pDel = 0;
- sqlite3 *db = pParse->db;
memset(&compLeft, 0, sizeof(Expr));
memset(&compRight, 0, sizeof(Expr));
memset(&exprAnd, 0, sizeof(Expr));
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
- if( db->mallocFailed==0 ){
- exprAnd.op = TK_AND;
- exprAnd.pLeft = &compLeft;
- exprAnd.pRight = &compRight;
- compLeft.op = TK_GE;
- compLeft.pLeft = pDel;
- compLeft.pRight = pExpr->x.pList->a[0].pExpr;
- compRight.op = TK_LE;
- compRight.pLeft = pDel;
- compRight.pRight = pExpr->x.pList->a[1].pExpr;
- exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
- if( xJump ){
- xJump(pParse, &exprAnd, dest, jumpIfNull);
- }else{
- /* Mark the expression is being from the ON or USING clause of a join
- ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
- ** it into the Parse.pConstExpr list. We should use a new bit for this,
- ** for clarity, but we are out of bits in the Expr.flags field so we
- ** have to reuse the EP_FromJoin bit. Bummer. */
- pDel->flags |= EP_FromJoin;
- sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
- }
- sqlite3ReleaseTempReg(pParse, regFree1);
- }
- sqlite3ExprDelete(db, pDel);
+ exprNodeCopy(&exprX, pExpr->pLeft);
+ exprAnd.op = TK_AND;
+ exprAnd.pLeft = &compLeft;
+ exprAnd.pRight = &compRight;
+ compLeft.op = TK_GE;
+ compLeft.pLeft = &exprX;
+ compLeft.pRight = pExpr->x.pList->a[0].pExpr;
+ compRight.op = TK_LE;
+ compRight.pLeft = &exprX;
+ compRight.pRight = pExpr->x.pList->a[1].pExpr;
+ exprToRegister(&exprX, exprCodeVector(pParse, &exprX, ®Free1));
+ if( xJump ){
+ xJump(pParse, &exprAnd, dest, jumpIfNull);
+ }else{
+ /* Mark the expression is being from the ON or USING clause of a join
+ ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
+ ** it into the Parse.pConstExpr list. We should use a new bit for this,
+ ** for clarity, but we are out of bits in the Expr.flags field so we
+ ** have to reuse the EP_FromJoin bit. Bummer. */
+ exprX.flags |= EP_FromJoin;
+ sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
+ }
+ sqlite3ReleaseTempReg(pParse, regFree1);
/* Ensure adequate test coverage */
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 );
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 );
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 );
@@ -4776,27 +4426,22 @@
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
if( NEVER(pExpr==0) ) return; /* No way this can happen */
op = pExpr->op;
switch( op ){
- case TK_AND:
+ case TK_AND: {
+ int d2 = sqlite3VdbeMakeLabel(pParse);
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3VdbeResolveLabel(v, d2);
+ break;
+ }
case TK_OR: {
- Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
- if( pAlt!=pExpr ){
- sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
- }else if( op==TK_AND ){
- int d2 = sqlite3VdbeMakeLabel(pParse);
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
- jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
- }else{
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- }
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
break;
}
case TK_NOT: {
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
@@ -4835,11 +4480,11 @@
if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted));
+ r1, r2, dest, jumpIfNull);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
@@ -4878,13 +4523,13 @@
break;
}
#endif
default: {
default_expr:
- if( ExprAlwaysTrue(pExpr) ){
+ if( exprAlwaysTrue(pExpr) ){
sqlite3VdbeGoto(v, dest);
- }else if( ExprAlwaysFalse(pExpr) ){
+ }else if( exprAlwaysFalse(pExpr) ){
/* No-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
VdbeCoverage(v);
@@ -4948,27 +4593,22 @@
assert( pExpr->op!=TK_LE || op==OP_Gt );
assert( pExpr->op!=TK_GT || op==OP_Le );
assert( pExpr->op!=TK_GE || op==OP_Lt );
switch( pExpr->op ){
- case TK_AND:
+ case TK_AND: {
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ break;
+ }
case TK_OR: {
- Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
- if( pAlt!=pExpr ){
- sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
- }else if( pExpr->op==TK_AND ){
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- }else{
- int d2 = sqlite3VdbeMakeLabel(pParse);
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
- jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
- }
+ int d2 = sqlite3VdbeMakeLabel(pParse);
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3VdbeResolveLabel(v, d2);
break;
}
case TK_NOT: {
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
@@ -5010,11 +4650,11 @@
if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted));
+ r1, r2, dest, jumpIfNull);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
@@ -5053,13 +4693,13 @@
break;
}
#endif
default: {
default_expr:
- if( ExprAlwaysFalse(pExpr) ){
+ if( exprAlwaysFalse(pExpr) ){
sqlite3VdbeGoto(v, dest);
- }else if( ExprAlwaysTrue(pExpr) ){
+ }else if( exprAlwaysTrue(pExpr) ){
/* no-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
VdbeCoverage(v);
@@ -5175,21 +4815,24 @@
return 1;
}
return 2;
}
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
- if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
+ if( pA->op==TK_FUNCTION ){
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
#ifndef SQLITE_OMIT_WINDOWFUNC
- assert( pA->op==pB->op );
- if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){
- return 2;
- }
+ /* Justification for the assert():
+ ** window functions have p->op==TK_FUNCTION but aggregate functions
+ ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
+ ** function and a window function should have failed before reaching
+ ** this point. And, it is not possible to have a window function and
+ ** a scalar function with the same name and number of arguments. So
+ ** if we reach this point, either A and B both window functions or
+ ** neither are a window functions. */
+ assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
if( ExprHasProperty(pA,EP_WinFunc) ){
- if( sqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){
- return 2;
- }
+ if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
}
#endif
}else if( pA->op==TK_NULL ){
return 0;
}else if( pA->op==TK_COLLATE ){
@@ -5196,12 +4839,11 @@
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
}else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2;
}
}
- if( (pA->flags & (EP_Distinct|EP_Commuted))
- != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
+ if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( (combinedFlags & EP_TokenOnly)==0 ){
if( combinedFlags & EP_xIsSelect ) return 2;
if( (combinedFlags & EP_FixedCol)==0
&& sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
@@ -5209,37 +4851,20 @@
if( pA->op!=TK_STRING
&& pA->op!=TK_TRUEFALSE
&& (combinedFlags & EP_Reduced)==0
){
if( pA->iColumn!=pB->iColumn ) return 2;
- if( pA->op2!=pB->op2 ){
- if( pA->op==TK_TRUTH ) return 2;
- if( pA->op==TK_FUNCTION && iTab<0 ){
- /* Ex: CREATE TABLE t1(a CHECK( aop!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
- return 2;
- }
+ if( pA->iTable!=pB->iTable
+ && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
}
return 0;
}
/*
-** Compare two ExprList objects. Return 0 if they are identical, 1
-** if they are certainly different, or 2 if it is not possible to
-** determine if they are identical or not.
+** Compare two ExprList objects. Return 0 if they are identical and
+** non-zero if they differ in any way.
**
** If any subelement of pB has Expr.iTable==(-1) then it is allowed
** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
**
** This routine might return non-zero for equivalent ExprLists. The
@@ -5254,15 +4879,14 @@
int i;
if( pA==0 && pB==0 ) return 0;
if( pA==0 || pB==0 ) return 1;
if( pA->nExpr!=pB->nExpr ) return 1;
for(i=0; inExpr; i++){
- int res;
Expr *pExprA = pA->a[i].pExpr;
Expr *pExprB = pB->a[i].pExpr;
- if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
- if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res;
+ if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
+ if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1;
}
return 0;
}
/*
@@ -5269,92 +4893,15 @@
** Like sqlite3ExprCompare() except COLLATE operators at the top-level
** are ignored.
*/
int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
return sqlite3ExprCompare(0,
- sqlite3ExprSkipCollateAndLikely(pA),
- sqlite3ExprSkipCollateAndLikely(pB),
+ sqlite3ExprSkipCollate(pA),
+ sqlite3ExprSkipCollate(pB),
iTab);
}
-/*
-** Return non-zero if Expr p can only be true if pNN is not NULL.
-**
-** Or if seenNot is true, return non-zero if Expr p can only be
-** non-NULL if pNN is not NULL
-*/
-static int exprImpliesNotNull(
- Parse *pParse, /* Parsing context */
- Expr *p, /* The expression to be checked */
- Expr *pNN, /* The expression that is NOT NULL */
- int iTab, /* Table being evaluated */
- int seenNot /* Return true only if p can be any non-NULL value */
-){
- assert( p );
- assert( pNN );
- if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){
- return pNN->op!=TK_NULL;
- }
- switch( p->op ){
- case TK_IN: {
- if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
- assert( ExprHasProperty(p,EP_xIsSelect)
- || (p->x.pList!=0 && p->x.pList->nExpr>0) );
- return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
- }
- case TK_BETWEEN: {
- ExprList *pList = p->x.pList;
- assert( pList!=0 );
- assert( pList->nExpr==2 );
- if( seenNot ) return 0;
- if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1)
- || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1)
- ){
- return 1;
- }
- return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
- }
- case TK_EQ:
- case TK_NE:
- case TK_LT:
- case TK_LE:
- case TK_GT:
- case TK_GE:
- case TK_PLUS:
- case TK_MINUS:
- case TK_BITOR:
- case TK_LSHIFT:
- case TK_RSHIFT:
- case TK_CONCAT:
- seenNot = 1;
- /* Fall thru */
- case TK_STAR:
- case TK_REM:
- case TK_BITAND:
- case TK_SLASH: {
- if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1;
- /* Fall thru into the next case */
- }
- case TK_SPAN:
- case TK_COLLATE:
- case TK_UPLUS:
- case TK_UMINUS: {
- return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
- }
- case TK_TRUTH: {
- if( seenNot ) return 0;
- if( p->op2!=TK_IS ) return 0;
- return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
- }
- case TK_BITNOT:
- case TK_NOT: {
- return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
- }
- }
- return 0;
-}
-
/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true. Return false if we cannot complete the proof or if pE2 might
** be false. Examples:
**
@@ -5386,20 +4933,20 @@
&& (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
|| sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
){
return 1;
}
- if( pE2->op==TK_NOTNULL
- && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
- ){
- return 1;
+ if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
+ Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
+ testcase( pX!=pE1->pLeft );
+ if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
}
return 0;
}
/*
-** This is the Expr node callback for sqlite3ExprImpliesNonNullRow().
+** This is the Expr node callback for sqlite3ExprImpliesNotNullRow().
** If the expression node requires that the table at pWalker->iCur
** have one or more non-NULL column, then set pWalker->eCode to 1 and abort.
**
** This routine controls an optimization. False positives (setting
** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives
@@ -5409,52 +4956,33 @@
testcase( pExpr->op==TK_AGG_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
switch( pExpr->op ){
case TK_ISNOT:
+ case TK_NOT:
case TK_ISNULL:
case TK_NOTNULL:
case TK_IS:
case TK_OR:
- case TK_VECTOR:
case TK_CASE:
case TK_IN:
case TK_FUNCTION:
- case TK_TRUTH:
testcase( pExpr->op==TK_ISNOT );
+ testcase( pExpr->op==TK_NOT );
testcase( pExpr->op==TK_ISNULL );
testcase( pExpr->op==TK_NOTNULL );
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_OR );
- testcase( pExpr->op==TK_VECTOR );
testcase( pExpr->op==TK_CASE );
testcase( pExpr->op==TK_IN );
testcase( pExpr->op==TK_FUNCTION );
- testcase( pExpr->op==TK_TRUTH );
return WRC_Prune;
case TK_COLUMN:
if( pWalker->u.iCur==pExpr->iTable ){
pWalker->eCode = 1;
return WRC_Abort;
}
- return WRC_Prune;
-
- case TK_AND:
- if( pWalker->eCode==0 ){
- sqlite3WalkExpr(pWalker, pExpr->pLeft);
- if( pWalker->eCode ){
- pWalker->eCode = 0;
- sqlite3WalkExpr(pWalker, pExpr->pRight);
- }
- }
- return WRC_Prune;
-
- case TK_BETWEEN:
- if( sqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){
- assert( pWalker->eCode );
- return WRC_Abort;
- }
return WRC_Prune;
/* Virtual tables are allowed to use constraints like x=NULL. So
** a term of the form x=y does not prove that y is not null if x
** is the column of a virtual table */
@@ -5473,11 +5001,10 @@
if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
|| (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
){
return WRC_Prune;
}
-
default:
return WRC_Continue;
}
}
@@ -5503,18 +5030,19 @@
** be non-NULL, then the LEFT JOIN can be safely converted into an
** ordinary join.
*/
int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
Walker w;
- p = sqlite3ExprSkipCollateAndLikely(p);
- if( p==0 ) return 0;
- if( p->op==TK_NOTNULL ){
- p = p->pLeft;
- }else{
- while( p->op==TK_AND ){
+ p = sqlite3ExprSkipCollate(p);
+ while( p ){
+ if( p->op==TK_NOTNULL ){
+ p = p->pLeft;
+ }else if( p->op==TK_AND ){
if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1;
p = p->pRight;
+ }else{
+ break;
}
}
w.xExprCallback = impliesNotNullRow;
w.xSelectCallback = 0;
w.xSelectCallback2 = 0;
@@ -5542,11 +5070,11 @@
** pWalker->u.pIdxCover->pIdx.
*/
static int exprIdxCover(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_COLUMN
&& pExpr->iTable==pWalker->u.pIdxCover->iCur
- && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
+ && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
){
pWalker->eCode = 1;
return WRC_Abort;
}
return WRC_Continue;
@@ -5593,30 +5121,26 @@
/*
** Count the number of references to columns.
*/
static int exprSrcCount(Walker *pWalker, Expr *pExpr){
- /* There was once a NEVER() on the second term on the grounds that
- ** sqlite3FunctionUsesThisSrc() was always called before
- ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
- ** been converted into TK_AGG_COLUMN. But this is no longer true due
- ** to window functions - sqlite3WindowRewrite() may now indirectly call
- ** FunctionUsesThisSrc() when creating a new sub-select. */
- if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
+ /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc()
+ ** is always called before sqlite3ExprAnalyzeAggregates() and so the
+ ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN. If
+ ** sqlite3FunctionUsesThisSrc() is used differently in the future, the
+ ** NEVER() will need to be removed. */
+ if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){
int i;
struct SrcCount *p = pWalker->u.pSrcCount;
SrcList *pSrc = p->pSrc;
int nSrc = pSrc ? pSrc->nSrc : 0;
for(i=0; iiTable==pSrc->a[i].iCursor ) break;
}
if( inThis++;
- }else if( nSrc==0 || pExpr->iTablea[0].iCursor ){
- /* In a well-formed parse tree (no name resolution errors),
- ** TK_COLUMN nodes with smaller Expr.iTable values are in an
- ** outer context. Those are the only ones to count as "other" */
+ }else{
p->nOther++;
}
}
return WRC_Continue;
}
@@ -5629,23 +5153,17 @@
*/
int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
Walker w;
struct SrcCount cnt;
assert( pExpr->op==TK_AGG_FUNCTION );
- memset(&w, 0, sizeof(w));
w.xExprCallback = exprSrcCount;
- w.xSelectCallback = sqlite3SelectWalkNoop;
+ w.xSelectCallback = 0;
w.u.pSrcCount = &cnt;
cnt.pSrc = pSrcList;
cnt.nThis = 0;
cnt.nOther = 0;
sqlite3WalkExprList(&w, pExpr->x.pList);
-#ifndef SQLITE_OMIT_WINDOWFUNC
- if( ExprHasProperty(pExpr, EP_WinFunc) ){
- sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
- }
-#endif
return cnt.nThis>0 || cnt.nOther==0;
}
/*
** Add a new element to the pAggInfo->aCol[] array. Return the index of
@@ -5870,15 +5388,12 @@
/*
** Deallocate a register, making available for reuse for some other
** purpose.
*/
void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
- if( iReg ){
- sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0);
- if( pParse->nTempRegaTempReg) ){
- pParse->aTempReg[pParse->nTempReg++] = iReg;
- }
+ if( iReg && pParse->nTempRegaTempReg) ){
+ pParse->aTempReg[pParse->nTempReg++] = iReg;
}
}
/*
** Allocate or deallocate a block of nReg consecutive registers.
@@ -5900,24 +5415,18 @@
void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
if( nReg==1 ){
sqlite3ReleaseTempReg(pParse, iReg);
return;
}
- sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0);
if( nReg>pParse->nRangeReg ){
pParse->nRangeReg = nReg;
pParse->iRangeReg = iReg;
}
}
/*
** Mark all temporary registers as being unavailable for reuse.
-**
-** Always invoke this procedure after coding a subroutine or co-routine
-** that might be invoked from other parts of the code, to ensure that
-** the sub/co-routine does not use registers in common with the code that
-** invokes the sub/co-routine.
*/
void sqlite3ClearTempRegCache(Parse *pParse){
pParse->nTempReg = 0;
pParse->nRangeReg = 0;
}
Index: src/fkey.c
==================================================================
--- src/fkey.c
+++ src/fkey.c
@@ -347,11 +347,11 @@
if( nIncr<0 ){
sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
VdbeCoverage(v);
}
for(i=0; inCol; i++){
- int iReg = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) + regData + 1;
+ int iReg = aiCol[i] + regData + 1;
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v);
}
if( isIgnore==0 ){
if( pIdx==0 ){
@@ -363,12 +363,11 @@
/* Invoke MustBeInt to coerce the child key value to an integer (i.e.
** apply the affinity of the parent key). If this fails, then there
** is no matching parent key. Before using MustBeInt, make a copy of
** the value. Otherwise, the value inserted into the child key column
** will have INTEGER affinity applied to it, which may not be correct. */
- sqlite3VdbeAddOp2(v, OP_SCopy,
- sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[0])+1+regData, regTemp);
+ sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
VdbeCoverage(v);
/* If the parent table is the same as the child table, and we are about
** to increment the constraint-counter (i.e. this is an INSERT operation),
@@ -391,13 +390,11 @@
int regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
for(i=0; ipFrom, aiCol[i])+1+regData,
- regTemp+i);
+ sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
}
/* If the parent table is the same as the child table, and we are about
** to increment the constraint-counter (i.e. this is an INSERT operation),
** then check if the row being inserted matches itself. If so, do not
@@ -409,15 +406,12 @@
** none of the child key values are).
*/
if( pTab==pFKey->pFrom && nIncr==1 ){
int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
for(i=0; ipFrom,aiCol[i])
- +1+regData;
- int iParent = 1+regData;
- iParent += sqlite3TableColumnToStorage(pIdx->pTable,
- pIdx->aiColumn[i]);
+ int iChild = aiCol[i]+1+regData;
+ int iParent = pIdx->aiColumn[i]+1+regData;
assert( pIdx->aiColumn[i]>=0 );
assert( aiCol[i]!=pTab->iPKey );
if( pIdx->aiColumn[i]==pTab->iPKey ){
/* The parent key is a composite key that includes the IPK column */
iParent = regData;
@@ -481,18 +475,18 @@
pExpr = sqlite3Expr(db, TK_REGISTER, 0);
if( pExpr ){
if( iCol>=0 && iCol!=pTab->iPKey ){
pCol = &pTab->aCol[iCol];
- pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1;
- pExpr->affExpr = pCol->affinity;
+ pExpr->iTable = regBase + iCol + 1;
+ pExpr->affinity = pCol->affinity;
zColl = pCol->zColl;
if( zColl==0 ) zColl = db->pDfltColl->zName;
pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl);
}else{
pExpr->iTable = regBase;
- pExpr->affExpr = SQLITE_AFF_INTEGER;
+ pExpr->affinity = SQLITE_AFF_INTEGER;
}
}
return pExpr;
}
@@ -595,11 +589,11 @@
iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iCol>=0 );
zCol = pFKey->pFrom->aCol[iCol].zName;
pRight = sqlite3Expr(db, TK_ID, zCol);
pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
- pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
+ pWhere = sqlite3ExprAnd(db, pWhere, pEq);
}
/* If the child table is the same as the parent table, then add terms
** to the WHERE clause that prevent this entry from being scanned.
** The added WHERE clause terms are like this:
@@ -629,15 +623,15 @@
i16 iCol = pIdx->aiColumn[i];
assert( iCol>=0 );
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
- pAll = sqlite3ExprAnd(pParse, pAll, pEq);
+ pAll = sqlite3ExprAnd(db, pAll, pEq);
}
pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
}
- pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
+ pWhere = sqlite3ExprAnd(db, pWhere, pNe);
}
/* Resolve the references in the WHERE clause. */
memset(&sNameContext, 0, sizeof(NameContext));
sNameContext.pSrcList = pSrc;
@@ -930,13 +924,11 @@
** FK counter for each row of the current table with non-NULL keys.
*/
Vdbe *v = sqlite3GetVdbe(pParse);
int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
for(i=0; inCol; i++){
- int iFromCol, iReg;
- iFromCol = pFKey->aCol[i].iFrom;
- iReg = sqlite3TableColumnToStorage(pFKey->pFrom,iFromCol) + regOld+1;
+ int iReg = pFKey->aCol[i].iFrom + regOld + 1;
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
}
continue;
@@ -1241,11 +1233,11 @@
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
);
- pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
+ pWhere = sqlite3ExprAnd(db, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
** The final WHEN clause will be like this:
**
** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
@@ -1257,29 +1249,21 @@
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
);
- pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
+ pWhen = sqlite3ExprAnd(db, pWhen, pEq);
}
if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
Expr *pNew;
if( action==OE_Cascade ){
pNew = sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0));
}else if( action==OE_SetDflt ){
- Column *pCol = pFKey->pFrom->aCol + iFromCol;
- Expr *pDflt;
- if( pCol->colFlags & COLFLAG_GENERATED ){
- testcase( pCol->colFlags & COLFLAG_VIRTUAL );
- testcase( pCol->colFlags & COLFLAG_STORED );
- pDflt = 0;
- }else{
- pDflt = pCol->pDflt;
- }
+ Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
if( pDflt ){
pNew = sqlite3ExprDup(db, pDflt, 0);
}else{
pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
}
@@ -1301,11 +1285,11 @@
tFrom.z = zFrom;
tFrom.n = nFrom;
pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
if( pRaise ){
- pRaise->affExpr = OE_Abort;
+ pRaise->affinity = OE_Abort;
}
pSelect = sqlite3SelectNew(pParse,
sqlite3ExprListAppend(pParse, 0, pRaise),
sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
pWhere,
@@ -1313,11 +1297,11 @@
);
pWhere = 0;
}
/* Disable lookaside memory allocation */
- DisableLookaside;
+ db->lookaside.bDisable++;
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
nFrom + 1 /* Space for pStep->zTarget */
@@ -1335,11 +1319,11 @@
pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
}
}
/* Re-enable the lookaside buffer, if it was disabled earlier. */
- EnableLookaside;
+ db->lookaside.bDisable--;
sqlite3ExprDelete(db, pWhere);
sqlite3ExprDelete(db, pWhen);
sqlite3ExprListDelete(db, pList);
sqlite3SelectDelete(db, pSelect);
@@ -1346,11 +1330,10 @@
if( db->mallocFailed==1 ){
fkTriggerDelete(db, pTrigger);
return 0;
}
assert( pStep!=0 );
- assert( pTrigger!=0 );
switch( action ){
case OE_Restrict:
pStep->op = TK_SELECT;
break;
Index: src/func.c
==================================================================
--- src/func.c
+++ src/func.c
@@ -14,13 +14,10 @@
** time functions, are implemented separately.)
*/
#include "sqliteInt.h"
#include
#include
-#ifndef SQLITE_OMIT_FLOATING_POINT
-#include
-#endif
#include "vdbeInt.h"
/*
** Return the collating function associated with a function.
*/
@@ -203,12 +200,10 @@
int nNeedle;
int typeHaystack, typeNeedle;
int N = 1;
int isText;
unsigned char firstChar;
- sqlite3_value *pC1 = 0;
- sqlite3_value *pC2 = 0;
UNUSED_PARAMETER(argc);
typeHaystack = sqlite3_value_type(argv[0]);
typeNeedle = sqlite3_value_type(argv[1]);
if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
@@ -217,26 +212,16 @@
if( nNeedle>0 ){
if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
zHaystack = sqlite3_value_blob(argv[0]);
zNeedle = sqlite3_value_blob(argv[1]);
isText = 0;
- }else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){
+ }else{
zHaystack = sqlite3_value_text(argv[0]);
zNeedle = sqlite3_value_text(argv[1]);
isText = 1;
- }else{
- pC1 = sqlite3_value_dup(argv[0]);
- zHaystack = sqlite3_value_text(pC1);
- if( zHaystack==0 ) goto endInstrOOM;
- nHaystack = sqlite3_value_bytes(pC1);
- pC2 = sqlite3_value_dup(argv[1]);
- zNeedle = sqlite3_value_text(pC2);
- if( zNeedle==0 ) goto endInstrOOM;
- nNeedle = sqlite3_value_bytes(pC2);
- isText = 1;
- }
- if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM;
+ }
+ if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
firstChar = zNeedle[0];
while( nNeedle<=nHaystack
&& (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
){
N++;
@@ -246,17 +231,10 @@
}while( isText && (zHaystack[0]&0xc0)==0x80 );
}
if( nNeedle>nHaystack ) N = 0;
}
sqlite3_result_int(context, N);
-endInstr:
- sqlite3_value_free(pC1);
- sqlite3_value_free(pC2);
- return;
-endInstrOOM:
- sqlite3_result_error_nomem(context);
- goto endInstr;
}
/*
** Implementation of the printf() function.
*/
@@ -406,14 +384,14 @@
r = sqlite3_value_double(argv[0]);
/* If Y==0 and X will fit in a 64-bit int,
** handle the rounding directly,
** otherwise use printf.
*/
- if( r<-4503599627370496.0 || r>+4503599627370496.0 ){
- /* The value has no fractional part so there is nothing to round */
- }else if( n==0 ){
- r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
+ if( n==0 && r>=0 && raLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
return;
}
+ assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
+
if( argc==3 ){
/* The escape character string must consist of a single UTF-8 character.
** Otherwise, return an error.
*/
const unsigned char *zEsc = sqlite3_value_text(argv[2]);
@@ -889,12 +871,10 @@
}
escape = sqlite3Utf8Read(&zEsc);
}else{
escape = pInfo->matchSet;
}
- zB = sqlite3_value_text(argv[0]);
- zA = sqlite3_value_text(argv[1]);
if( zA && zB ){
#ifdef SQLITE_TEST
sqlite3_like_count++;
#endif
sqlite3_result_int(context,
@@ -1816,28 +1796,43 @@
sqlite3OomFault(db);
}
}
/*
-** Re-register the built-in LIKE functions. The caseSensitive
+** Set the LIKEOPT flag on the 2-argument function with the given name.
+*/
+static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
+ FuncDef *pDef;
+ pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
+ if( ALWAYS(pDef) ){
+ pDef->funcFlags |= flagVal;
+ }
+ pDef = sqlite3FindFunction(db, zName, 3, SQLITE_UTF8, 0);
+ if( pDef ){
+ pDef->funcFlags |= flagVal;
+ }
+}
+
+/*
+** Register the built-in LIKE and GLOB functions. The caseSensitive
** parameter determines whether or not the LIKE operator is case
-** sensitive.
+** sensitive. GLOB is always case sensitive.
*/
void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
struct compareInfo *pInfo;
- int flags;
if( caseSensitive ){
pInfo = (struct compareInfo*)&likeInfoAlt;
- flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
}else{
pInfo = (struct compareInfo*)&likeInfoNorm;
- flags = SQLITE_FUNC_LIKE;
}
sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
- sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
- sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
+ sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
+ (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
+ setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
+ setLikeOptFlag(db, "like",
+ caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
}
/*
** pExpr points to an expression which implements a function. If
** it is appropriate to apply the LIKE optimization to that function
@@ -1907,35 +1902,30 @@
** are read-only after initialization is complete.
**
** For peak efficiency, put the most frequently used function last.
*/
static FuncDef aBuiltinFunc[] = {
-/***** Functions only available with SQLITE_TESTCTRL_INTERNAL_FUNCTIONS *****/
- TEST_FUNC(implies_nonnull_row, 2, INLINEFUNC_implies_nonnull_row, 0),
- TEST_FUNC(expr_compare, 2, INLINEFUNC_expr_compare, 0),
- TEST_FUNC(expr_implies_expr, 2, INLINEFUNC_expr_implies_expr, 0),
-#ifdef SQLITE_DEBUG
- TEST_FUNC(affinity, 1, INLINEFUNC_affinity, 0),
-#endif
-/***** Regular functions *****/
#ifdef SQLITE_SOUNDEX
FUNCTION(soundex, 1, 0, 0, soundexFunc ),
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
- SFUNCTION(load_extension, 1, 0, 0, loadExt ),
- SFUNCTION(load_extension, 2, 0, 0, loadExt ),
+ VFUNCTION(load_extension, 1, 0, 0, loadExt ),
+ VFUNCTION(load_extension, 2, 0, 0, loadExt ),
#endif
#if SQLITE_USER_AUTHENTICATION
FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
#endif
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
- INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
- INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
- INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+#ifdef SQLITE_DEBUG
+ FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY),
+#endif
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
SQLITE_FUNC_TYPEOF),
#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
@@ -1964,11 +1954,11 @@
FUNCTION(round, 2, 0, 0, roundFunc ),
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(hex, 1, 0, 0, hexFunc ),
- INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE),
+ FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
@@ -2004,16 +1994,19 @@
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
FUNCTION(unknown, -1, 0, 0, unknownFunc ),
#endif
FUNCTION(coalesce, 1, 0, 0, 0 ),
FUNCTION(coalesce, 0, 0, 0, 0 ),
- INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE),
+ FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
};
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
#endif
sqlite3WindowFunctions();
+#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
+ sqlite3AnalyzeFunctions();
+#endif
sqlite3RegisterDateTimeFunctions();
sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
#if 0 /* Enable to print out how the built-in functions are hashed */
{
Index: src/global.c
==================================================================
--- src/global.c
+++ src/global.c
@@ -85,10 +85,11 @@
** Bit 0x40 is set if the character is non-alphanumeric and can be used in an
** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any
** non-ASCII UTF character. Hence the test for whether or not a character is
** part of an identifier is 0x46.
*/
+#ifdef SQLITE_ASCII
const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
@@ -122,10 +123,11 @@
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */
};
+#endif
/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
** compatibility for legacy applications, the URI filename capability is
** disabled by default.
**
@@ -149,19 +151,12 @@
/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
-#if !defined(SQLITE_ALLOW_COVERING_INDEX_SCAN)
+#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
-#else
-# if !SQLITE_ALLOW_COVERING_INDEX_SCAN
-# error "Compile-time disabling of covering index scan using the\
- -DSQLITE_ALLOW_COVERING_INDEX_SCAN=0 option is deprecated.\
- Contact SQLite developers if this is a problem for you, and\
- delete this #error macro to continue with your build."
-# endif
#endif
/* The minimum PMA size is set to this value multiplied by the database
** page size in bytes.
*/
@@ -186,22 +181,13 @@
** number of bytes in each lookaside slot (should be a multiple of 8)
** and N is the number of slots. The lookaside-configuration can be
** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE)
** or at run-time for an individual database connection using
** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE);
-**
-** With the two-size-lookaside enhancement, less lookaside is required.
-** The default configuration of 1200,40 actually provides 30 1200-byte slots
-** and 93 128-byte slots, which is more lookaside than is available
-** using the older 1200,100 configuration without two-size-lookaside.
*/
#ifndef SQLITE_DEFAULT_LOOKASIDE
-# ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE
-# define SQLITE_DEFAULT_LOOKASIDE 1200,100 /* 120KB of memory */
-# else
-# define SQLITE_DEFAULT_LOOKASIDE 1200,40 /* 48KB of memory */
-# endif
+# define SQLITE_DEFAULT_LOOKASIDE 1200,100
#endif
/* The default maximum size of an in-memory database created using
** sqlite3_deserialize()
@@ -219,11 +205,10 @@
1, /* bCoreMutex */
SQLITE_THREADSAFE==1, /* bFullMutex */
SQLITE_USE_URI, /* bOpenUri */
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
0, /* bSmallMalloc */
- 1, /* bExtraSchemaChecks */
0x7ffffffe, /* mxStrlen */
0, /* neverCorrupt */
SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
SQLITE_STMTJRNL_SPILL, /* nStmtSpill */
{0,0,0,0,0,0,0,0}, /* m */
@@ -263,21 +248,29 @@
#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
0, /* bLocaltimeFault */
+ 0, /* bInternalFunctions */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
- 0, /* iPrngSeed */
};
/*
** Hash table for global functions - functions common to all
** database connections. After initialization, this table is
** read-only.
*/
FuncDefHash sqlite3BuiltinFunctions;
+
+/*
+** Constant tokens for values 0 and 1.
+*/
+const Token sqlite3IntTokens[] = {
+ { "0", 1 },
+ { "1", 1 }
+};
#ifdef VDBE_PROFILE
/*
** The following performance counter can be used in place of
** sqlite3Hwtime() for profiling. This is a no-op on standard builds.
Index: src/hwtime.h
==================================================================
--- src/hwtime.h
+++ src/hwtime.h
@@ -9,11 +9,11 @@
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 and x86_64 class CPUs.
+** counters for x86 class CPUs.
*/
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H
/*
@@ -20,13 +20,12 @@
** The following routine only works on pentium-class (or newer) processors.
** It uses the RDTSC opcode to read the cycle count value out of the
** processor and returns that value. This can be used for high-res
** profiling.
*/
-#if !defined(__STRICT_ANSI__) && \
- (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
+#if (defined(__GNUC__) || defined(_MSC_VER)) && \
+ (defined(i386) || defined(__i386__) || defined(_M_IX86))
#if defined(__GNUC__)
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned int lo, hi;
@@ -43,19 +42,19 @@
}
}
#endif
-#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
+#elif (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long val;
__asm__ __volatile__ ("rdtsc" : "=A" (val));
return val;
}
-#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
+#elif (defined(__GNUC__) && defined(__ppc__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long long retval;
unsigned long junk;
__asm__ __volatile__ ("\n\
@@ -68,18 +67,19 @@
return retval;
}
#else
+ #error Need implementation of sqlite3Hwtime() for your platform.
+
/*
- ** asm() is needed for hardware timing support. Without asm(),
- ** disable the sqlite3Hwtime() routine.
- **
- ** sqlite3Hwtime() is only used for some obscure debugging
- ** and analysis configurations, not in any deliverable, so this
- ** should not be a great loss.
+ ** To compile without implementing sqlite3Hwtime() for your platform,
+ ** you can remove the above #error and use the following
+ ** stub function. You will lose timing support for many
+ ** of the debugging and testing utilities, but it should at
+ ** least compile and run.
*/
sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
#endif
#endif /* !defined(SQLITE_HWTIME_H) */
Index: src/insert.c
==================================================================
--- src/insert.c
+++ src/insert.c
@@ -35,11 +35,11 @@
v = sqlite3GetVdbe(pParse);
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
sqlite3TableLock(pParse, iDb, pTab->tnum,
(opcode==OP_OpenWrite)?1:0, pTab->zName);
if( HasRowid(pTab) ){
- sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol);
+ sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
VdbeComment((v, "%s", pTab->zName));
}else{
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pPk!=0 );
assert( pPk->tnum==pTab->tnum );
@@ -86,23 +86,22 @@
sqlite3OomFault(db);
return 0;
}
for(n=0; nnColumn; n++){
i16 x = pIdx->aiColumn[n];
- char aff;
if( x>=0 ){
- aff = pTab->aCol[x].affinity;
+ pIdx->zColAff[n] = pTab->aCol[x].affinity;
}else if( x==XN_ROWID ){
- aff = SQLITE_AFF_INTEGER;
+ pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
}else{
+ char aff;
assert( x==XN_EXPR );
assert( pIdx->aColExpr!=0 );
aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
+ if( aff==0 ) aff = SQLITE_AFF_BLOB;
+ pIdx->zColAff[n] = aff;
}
- if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC;
- pIdx->zColAff[n] = aff;
}
pIdx->zColAff[n] = 0;
}
return pIdx->zColAff;
@@ -127,29 +126,26 @@
** 'C' NUMERIC
** 'D' INTEGER
** 'E' REAL
*/
void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
- int i, j;
+ int i;
char *zColAff = pTab->zColAff;
if( zColAff==0 ){
sqlite3 *db = sqlite3VdbeDb(v);
zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
if( !zColAff ){
sqlite3OomFault(db);
return;
}
- for(i=j=0; inCol; i++){
- assert( pTab->aCol[i].affinity!=0 );
- if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
- zColAff[j++] = pTab->aCol[i].affinity;
- }
+ for(i=0; inCol; i++){
+ zColAff[i] = pTab->aCol[i].affinity;
}
do{
- zColAff[j--] = 0;
- }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB );
+ zColAff[i--] = 0;
+ }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
pTab->zColAff = zColAff;
}
assert( zColAff!=0 );
i = sqlite3Strlen30NN(zColAff);
if( i ){
@@ -198,123 +194,10 @@
}
#endif
}
return 0;
}
-
-/* This walker callback will compute the union of colFlags flags for all
-** referenced columns in a CHECK constraint or generated column expression.
-*/
-static int exprColumnFlagUnion(Walker *pWalker, Expr *pExpr){
- if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 ){
- assert( pExpr->iColumn < pWalker->u.pTab->nCol );
- pWalker->eCode |= pWalker->u.pTab->aCol[pExpr->iColumn].colFlags;
- }
- return WRC_Continue;
-}
-
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
-/*
-** All regular columns for table pTab have been puts into registers
-** starting with iRegStore. The registers that correspond to STORED
-** or VIRTUAL columns have not yet been initialized. This routine goes
-** back and computes the values for those columns based on the previously
-** computed normal columns.
-*/
-void sqlite3ComputeGeneratedColumns(
- Parse *pParse, /* Parsing context */
- int iRegStore, /* Register holding the first column */
- Table *pTab /* The table */
-){
- int i;
- Walker w;
- Column *pRedo;
- int eProgress;
- VdbeOp *pOp;
-
- assert( pTab->tabFlags & TF_HasGenerated );
- testcase( pTab->tabFlags & TF_HasVirtual );
- testcase( pTab->tabFlags & TF_HasStored );
-
- /* Before computing generated columns, first go through and make sure
- ** that appropriate affinity has been applied to the regular columns
- */
- sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
- if( (pTab->tabFlags & TF_HasStored)!=0
- && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity
- ){
- /* Change the OP_Affinity argument to '@' (NONE) for all stored
- ** columns. '@' is the no-op affinity and those columns have not
- ** yet been computed. */
- int ii, jj;
- char *zP4 = pOp->p4.z;
- assert( zP4!=0 );
- assert( pOp->p4type==P4_DYNAMIC );
- for(ii=jj=0; zP4[jj]; ii++){
- if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
- continue;
- }
- if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
- zP4[jj] = SQLITE_AFF_NONE;
- }
- jj++;
- }
- }
-
- /* Because there can be multiple generated columns that refer to one another,
- ** this is a two-pass algorithm. On the first pass, mark all generated
- ** columns as "not available".
- */
- for(i=0; inCol; i++){
- if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){
- testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL );
- testcase( pTab->aCol[i].colFlags & COLFLAG_STORED );
- pTab->aCol[i].colFlags |= COLFLAG_NOTAVAIL;
- }
- }
-
- w.u.pTab = pTab;
- w.xExprCallback = exprColumnFlagUnion;
- w.xSelectCallback = 0;
- w.xSelectCallback2 = 0;
-
- /* On the second pass, compute the value of each NOT-AVAILABLE column.
- ** Companion code in the TK_COLUMN case of sqlite3ExprCodeTarget() will
- ** compute dependencies and mark remove the COLSPAN_NOTAVAIL mark, as
- ** they are needed.
- */
- pParse->iSelfTab = -iRegStore;
- do{
- eProgress = 0;
- pRedo = 0;
- for(i=0; inCol; i++){
- Column *pCol = pTab->aCol + i;
- if( (pCol->colFlags & COLFLAG_NOTAVAIL)!=0 ){
- int x;
- pCol->colFlags |= COLFLAG_BUSY;
- w.eCode = 0;
- sqlite3WalkExpr(&w, pCol->pDflt);
- pCol->colFlags &= ~COLFLAG_BUSY;
- if( w.eCode & COLFLAG_NOTAVAIL ){
- pRedo = pCol;
- continue;
- }
- eProgress = 1;
- assert( pCol->colFlags & COLFLAG_GENERATED );
- x = sqlite3TableColumnToStorage(pTab, i) + iRegStore;
- sqlite3ExprCodeGeneratedColumn(pParse, pCol, x);
- pCol->colFlags &= ~COLFLAG_NOTAVAIL;
- }
- }
- }while( pRedo && eProgress );
- if( pRedo ){
- sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zName);
- }
- pParse->iSelfTab = 0;
-}
-#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
-
#ifndef SQLITE_OMIT_AUTOINCREMENT
/*
** Locate or create an AutoincInfo structure associated with table pTab
** which is in database iDb. Return the register number for the register
@@ -619,11 +502,11 @@
*/
void sqlite3Insert(
Parse *pParse, /* Parser context */
SrcList *pTabList, /* Name of table into which we are inserting */
Select *pSelect, /* A SELECT statement to use as the data source */
- IdList *pColumn, /* Column names corresponding to IDLIST, or NULL. */
+ IdList *pColumn, /* Column names corresponding to IDLIST. */
int onError, /* How to handle constraint errors */
Upsert *pUpsert /* ON CONFLICT clauses for upsert, or NULL */
){
sqlite3 *db; /* The main database structure */
Table *pTab; /* The table to insert into. aka TABLE */
@@ -644,11 +527,10 @@
u8 useTempTable = 0; /* Store SELECT results in intermediate table */
u8 appendFlag = 0; /* True if the insert is likely to be an append */
u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
u8 bIdListInOrder; /* True if IDLIST is in table order */
ExprList *pList = 0; /* List of VALUES() to be inserted */
- int iRegStore; /* Register in which to store next column */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */
int regRowCount = 0; /* Memory cell used for the row counter */
@@ -752,12 +634,12 @@
/* If this is an AUTOINCREMENT table, look up the sequence number in the
** sqlite_sequence table and store it in memory cell regAutoinc.
*/
regAutoinc = autoIncBegin(pParse, iDb, pTab);
- /* Allocate a block registers to hold the rowid and the values
- ** for all columns of the new row.
+ /* Allocate registers for holding the rowid of the new row,
+ ** the content of the new row, and the assembled row record.
*/
regRowid = regIns = pParse->nMem+1;
pParse->nMem += pTab->nCol + 1;
if( IsVirtual(pTab) ){
regRowid++;
@@ -772,21 +654,13 @@
** If the table has an INTEGER PRIMARY KEY column and that column
** is named in the IDLIST, then record in the ipkColumn variable
** the index into IDLIST of the primary key column. ipkColumn is
** the index of the primary key as it appears in IDLIST, not as
** is appears in the original table. (The index of the INTEGER
- ** PRIMARY KEY in the original table is pTab->iPKey.) After this
- ** loop, if ipkColumn==(-1), that means that integer primary key
- ** is unspecified, and hence the table is either WITHOUT ROWID or
- ** it will automatically generated an integer primary key.
- **
- ** bIdListInOrder is true if the columns in IDLIST are in storage
- ** order. This enables an optimization that avoids shuffling the
- ** columns into storage order. False negatives are harmless,
- ** but false positives will cause database corruption.
+ ** PRIMARY KEY in the original table is pTab->iPKey.)
*/
- bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
+ bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
if( pColumn ){
for(i=0; inId; i++){
pColumn->a[i].idx = -1;
}
for(i=0; inId; i++){
@@ -795,18 +669,10 @@
pColumn->a[i].idx = j;
if( i!=j ) bIdListInOrder = 0;
if( j==pTab->iPKey ){
ipkColumn = i; assert( !withoutRowid );
}
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){
- sqlite3ErrorMsg(pParse,
- "cannot INSERT into generated column \"%s\"",
- pTab->aCol[j].zName);
- goto insert_cleanup;
- }
-#endif
break;
}
}
if( j>=pTab->nCol ){
if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
@@ -912,30 +778,17 @@
** key, the set the ipkColumn variable to the integer primary key
** column index in the original table definition.
*/
if( pColumn==0 && nColumn>0 ){
ipkColumn = pTab->iPKey;
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- if( ipkColumn>=0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){
- testcase( pTab->tabFlags & TF_HasVirtual );
- testcase( pTab->tabFlags & TF_HasStored );
- for(i=ipkColumn-1; i>=0; i--){
- if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){
- testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL );
- testcase( pTab->aCol[i].colFlags & COLFLAG_STORED );
- ipkColumn--;
- }
- }
- }
-#endif
}
/* Make sure the number of columns in the source data matches the number
** of columns to be inserted into the table.
*/
for(i=0; inCol; i++){
- if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++;
+ nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
}
if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
sqlite3ErrorMsg(pParse,
"table %S has %d columns but %d values were supplied",
pTabList, 0, pTab->nCol-nHidden, nColumn);
@@ -959,35 +812,27 @@
/* If this is not a view, open the table and and all indices */
if( !isView ){
int nIdx;
nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
&iDataCur, &iIdxCur);
- aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
+ aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
if( aRegIdx==0 ){
goto insert_cleanup;
}
for(i=0, pIdx=pTab->pIndex; ipNext, i++){
assert( pIdx );
aRegIdx[i] = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}
- aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */
}
#ifndef SQLITE_OMIT_UPSERT
if( pUpsert ){
if( IsVirtual(pTab) ){
sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
pTab->zName);
goto insert_cleanup;
}
- if( pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "cannot UPSERT a view");
- goto insert_cleanup;
- }
- if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){
- goto insert_cleanup;
- }
pTabList->a[0].iCursor = iDataCur;
pUpsert->pUpsertSrc = pTabList;
pUpsert->regData = regData;
pUpsert->iDataCur = iDataCur;
pUpsert->iIdxCur = iIdxCur;
@@ -1018,94 +863,13 @@
** C: yield X, at EOF goto D
** insert the select result into
from R..R+n
** goto C
** D: ...
*/
- sqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0, 0);
addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
VdbeCoverage(v);
- if( ipkColumn>=0 ){
- /* tag-20191021-001: If the INTEGER PRIMARY KEY is being generated by the
- ** SELECT, go ahead and copy the value into the rowid slot now, so that
- ** the value does not get overwritten by a NULL at tag-20191021-002. */
- sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
- }
- }
-
- /* Compute data for ordinary columns of the new entry. Values
- ** are written in storage order into registers starting with regData.
- ** Only ordinary columns are computed in this loop. The rowid
- ** (if there is one) is computed later and generated columns are
- ** computed after the rowid since they might depend on the value
- ** of the rowid.
- */
- nHidden = 0;
- iRegStore = regData; assert( regData==regRowid+1 );
- for(i=0; inCol; i++, iRegStore++){
- int k;
- u32 colFlags;
- assert( i>=nHidden );
- if( i==pTab->iPKey ){
- /* tag-20191021-002: References to the INTEGER PRIMARY KEY are filled
- ** using the rowid. So put a NULL in the IPK slot of the record to avoid
- ** using excess space. The file format definition requires this extra
- ** NULL - we cannot optimize further by skipping the column completely */
- sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
- continue;
- }
- if( ((colFlags = pTab->aCol[i].colFlags) & COLFLAG_NOINSERT)!=0 ){
- nHidden++;
- if( (colFlags & COLFLAG_VIRTUAL)!=0 ){
- /* Virtual columns do not participate in OP_MakeRecord. So back up
- ** iRegStore by one slot to compensate for the iRegStore++ in the
- ** outer for() loop */
- iRegStore--;
- continue;
- }else if( (colFlags & COLFLAG_STORED)!=0 ){
- /* Stored columns are computed later. But if there are BEFORE
- ** triggers, the slots used for stored columns will be OP_Copy-ed
- ** to a second block of registers, so the register needs to be
- ** initialized to NULL to avoid an uninitialized register read */
- if( tmask & TRIGGER_BEFORE ){
- sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
- }
- continue;
- }else if( pColumn==0 ){
- /* Hidden columns that are not explicitly named in the INSERT
- ** get there default value */
- sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
- continue;
- }
- }
- if( pColumn ){
- for(j=0; jnId && pColumn->a[j].idx!=i; j++){}
- if( j>=pColumn->nId ){
- /* A column not named in the insert column list gets its
- ** default value */
- sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
- continue;
- }
- k = j;
- }else if( nColumn==0 ){
- /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */
- sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
- continue;
- }else{
- k = i - nHidden;
- }
-
- if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore);
- }else if( pSelect ){
- if( regFromSelect!=regData ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore);
- }
- }else{
- sqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore);
- }
- }
-
+ }
/* Run the BEFORE and INSTEAD OF triggers, if there are any
*/
endOfLoop = sqlite3VdbeMakeLabel(pParse);
if( tmask & TRIGGER_BEFORE ){
@@ -1137,25 +901,29 @@
/* Cannot have triggers on a virtual table. If it were possible,
** this block would have to account for hidden column.
*/
assert( !IsVirtual(pTab) );
- /* Copy the new data already generated. */
- assert( pTab->nNVCol>0 );
- sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1);
-
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- /* Compute the new value for generated columns after all other
- ** columns have already been computed. This must be done after
- ** computing the ROWID in case one of the generated columns
- ** refers to the ROWID. */
- if( pTab->tabFlags & TF_HasGenerated ){
- testcase( pTab->tabFlags & TF_HasVirtual );
- testcase( pTab->tabFlags & TF_HasStored );
- sqlite3ComputeGeneratedColumns(pParse, regCols+1, pTab);
- }
-#endif
+ /* Create the new column data
+ */
+ for(i=j=0; inCol; i++){
+ if( pColumn ){
+ for(j=0; jnId; j++){
+ if( pColumn->a[j].idx==i ) break;
+ }
+ }
+ if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId)
+ || (pColumn==0 && IsOrdinaryHiddenColumn(&pTab->aCol[i])) ){
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
+ }else if( useTempTable ){
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1);
+ }else{
+ assert( pSelect==0 ); /* Otherwise useTempTable is true */
+ sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
+ }
+ if( pColumn==0 && !IsOrdinaryHiddenColumn(&pTab->aCol[i]) ) j++;
+ }
/* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
** do not attempt any conversions before assembling the record.
** If this is a real table, attempt conversions as required by the
** table column affinities.
@@ -1169,21 +937,23 @@
pTab, regCols-pTab->nCol-1, onError, endOfLoop);
sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
}
+ /* Compute the content of the next row to insert into a range of
+ ** registers beginning at regIns.
+ */
if( !isView ){
if( IsVirtual(pTab) ){
/* The row that the VUpdate opcode will delete: none */
sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
}
if( ipkColumn>=0 ){
- /* Compute the new rowid */
if( useTempTable ){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid);
}else if( pSelect ){
- /* Rowid already initialized at tag-20191021-001 */
+ sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
}else{
Expr *pIpk = pList->a[ipkColumn].pExpr;
if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){
sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
appendFlag = 1;
@@ -1212,19 +982,49 @@
sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
appendFlag = 1;
}
autoIncStep(pParse, regAutoinc, regRowid);
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- /* Compute the new value for generated columns after all other
- ** columns have already been computed. This must be done after
- ** computing the ROWID in case one of the generated columns
- ** is derived from the INTEGER PRIMARY KEY. */
- if( pTab->tabFlags & TF_HasGenerated ){
- sqlite3ComputeGeneratedColumns(pParse, regRowid+1, pTab);
- }
-#endif
+ /* Compute data for all columns of the new entry, beginning
+ ** with the first column.
+ */
+ nHidden = 0;
+ for(i=0; inCol; i++){
+ int iRegStore = regRowid+1+i;
+ if( i==pTab->iPKey ){
+ /* The value of the INTEGER PRIMARY KEY column is always a NULL.
+ ** Whenever this column is read, the rowid will be substituted
+ ** in its place. Hence, fill this column with a NULL to avoid
+ ** taking up data space with information that will never be used.
+ ** As there may be shallow copies of this value, make it a soft-NULL */
+ sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
+ continue;
+ }
+ if( pColumn==0 ){
+ if( IsHiddenColumn(&pTab->aCol[i]) ){
+ j = -1;
+ nHidden++;
+ }else{
+ j = i - nHidden;
+ }
+ }else{
+ for(j=0; jnId; j++){
+ if( pColumn->a[j].idx==i ) break;
+ }
+ }
+ if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
+ sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
+ }else if( useTempTable ){
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
+ }else if( pSelect ){
+ if( regFromSelect!=regData ){
+ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
+ }
+ }else{
+ sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
+ }
+ }
/* Generate code to check constraints and generate index keys and
** do the insertion.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -1250,11 +1050,13 @@
** flag in the second case as if any REPLACE constraint is hit, an
** OP_Delete or OP_IdxDelete instruction will be executed on each
** cursor that is disturbed. And these instructions both clear the
** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
** functionality. */
- bUseSeek = (isReplace==0 || !sqlite3VdbeHasSubProgram(v));
+ bUseSeek = (isReplace==0 || (pTrigger==0 &&
+ ((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0)
+ ));
sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
regIns, aRegIdx, 0, appendFlag, bUseSeek
);
}
}
@@ -1279,19 +1081,10 @@
sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrInsTop);
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
}else if( pSelect ){
sqlite3VdbeGoto(v, addrCont);
-#ifdef SQLITE_DEBUG
- /* If we are jumping back to an OP_Yield that is preceded by an
- ** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the
- ** OP_ReleaseReg will be included in the loop. */
- if( sqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){
- assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield );
- sqlite3VdbeChangeP5(v, 1);
- }
-#endif
sqlite3VdbeJumpHere(v, addrInsTop);
}
insert_end:
/* Update the sqlite_sequence table by storing the content of the
@@ -1431,18 +1224,10 @@
** registers identified by aRegIdx[]. No index entry is created for
** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
** the same as the order of indices on the linked list of indices
** at pTab->pIndex.
**
-** (2019-05-07) The generated code also creates a new record for the
-** main table, if pTab is a rowid table, and stores that record in the
-** register identified by aRegIdx[nIdx] - in other words in the first
-** entry of aRegIdx[] past the last index. It is important that the
-** record be generated during constraint checks to avoid affinity changes
-** to the register content that occur after constraint checks but before
-** the new record is inserted.
-**
** The caller must have already opened writeable cursors on the main
** table and all applicable indices (that is to say, all indices for which
** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor
@@ -1510,26 +1295,20 @@
sqlite3 *db; /* Database connection */
int i; /* loop counter */
int ix; /* Index loop counter */
int nCol; /* Number of columns */
int onError; /* Conflict resolution strategy */
+ int addr1; /* Address of jump instruction */
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
Index *pUpIdx = 0; /* Index to which to apply the upsert */
u8 isUpdate; /* True if this is an UPDATE operation */
u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */
int upsertBypass = 0; /* Address of Goto to bypass upsert subroutine */
int upsertJump = 0; /* Address of Goto that jumps into upsert subroutine */
int ipkTop = 0; /* Top of the IPK uniqueness check */
int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */
- /* Variables associated with retesting uniqueness constraints after
- ** replace triggers fire have run */
- int regTrigCnt; /* Register used to count replace trigger invocations */
- int addrRecheck = 0; /* Jump here to recheck all uniqueness constraints */
- int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */
- Trigger *pTrigger; /* List of DELETE triggers on the table pTab */
- int nReplaceTrig = 0; /* Number of replace triggers coded */
isUpdate = regOldData!=0;
db = pParse->db;
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
@@ -1552,107 +1331,67 @@
VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
iDataCur, iIdxCur, regNewData, regOldData, pkChng));
/* Test all NOT NULL constraints.
*/
- if( pTab->tabFlags & TF_HasNotNull ){
- int b2ndPass = 0; /* True if currently running 2nd pass */
- int nSeenReplace = 0; /* Number of ON CONFLICT REPLACE operations */
- int nGenerated = 0; /* Number of generated columns with NOT NULL */
- while(1){ /* Make 2 passes over columns. Exit loop via "break" */
- for(i=0; iaCol[i]; /* The column to check for NOT NULL */
- int isGenerated; /* non-zero if column is generated */
- onError = pCol->notNull;
- if( onError==OE_None ) continue; /* No NOT NULL on this column */
- if( i==pTab->iPKey ){
- continue; /* ROWID is never NULL */
- }
- isGenerated = pCol->colFlags & COLFLAG_GENERATED;
- if( isGenerated && !b2ndPass ){
- nGenerated++;
- continue; /* Generated columns processed on 2nd pass */
- }
- if( aiChng && aiChng[i]<0 && !isGenerated ){
- /* Do not check NOT NULL on columns that do not change */
- continue;
- }
- if( overrideError!=OE_Default ){
- onError = overrideError;
- }else if( onError==OE_Default ){
- onError = OE_Abort;
- }
- if( onError==OE_Replace ){
- if( b2ndPass /* REPLACE becomes ABORT on the 2nd pass */
- || pCol->pDflt==0 /* REPLACE is ABORT if no DEFAULT value */
- ){
- testcase( pCol->colFlags & COLFLAG_VIRTUAL );
- testcase( pCol->colFlags & COLFLAG_STORED );
- testcase( pCol->colFlags & COLFLAG_GENERATED );
- onError = OE_Abort;
- }else{
- assert( !isGenerated );
- }
- }else if( b2ndPass && !isGenerated ){
- continue;
- }
- assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
- || onError==OE_Ignore || onError==OE_Replace );
- testcase( i!=sqlite3TableColumnToStorage(pTab, i) );
- iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1;
- switch( onError ){
- case OE_Replace: {
- int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, iReg);
- VdbeCoverage(v);
- assert( (pCol->colFlags & COLFLAG_GENERATED)==0 );
- nSeenReplace++;
- sqlite3ExprCode(pParse, pCol->pDflt, iReg);
- sqlite3VdbeJumpHere(v, addr1);
- break;
- }
- case OE_Abort:
- sqlite3MayAbort(pParse);
- /* Fall through */
- case OE_Rollback:
- case OE_Fail: {
- char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
- pCol->zName);
- sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL,
- onError, iReg);
- sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
- sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
- VdbeCoverage(v);
- break;
- }
- default: {
- assert( onError==OE_Ignore );
- sqlite3VdbeAddOp2(v, OP_IsNull, iReg, ignoreDest);
- VdbeCoverage(v);
- break;
- }
- } /* end switch(onError) */
- } /* end loop i over columns */
- if( nGenerated==0 && nSeenReplace==0 ){
- /* If there are no generated columns with NOT NULL constraints
- ** and no NOT NULL ON CONFLICT REPLACE constraints, then a single
- ** pass is sufficient */
- break;
- }
- if( b2ndPass ) break; /* Never need more than 2 passes */
- b2ndPass = 1;
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- if( nSeenReplace>0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){
- /* If any NOT NULL ON CONFLICT REPLACE constraints fired on the
- ** first pass, recomputed values for all generated columns, as
- ** those values might depend on columns affected by the REPLACE.
- */
- sqlite3ComputeGeneratedColumns(pParse, regNewData+1, pTab);
- }
-#endif
- } /* end of 2-pass loop */
- } /* end if( has-not-null-constraints ) */
+ for(i=0; iiPKey ){
+ continue; /* ROWID is never NULL */
+ }
+ if( aiChng && aiChng[i]<0 ){
+ /* Don't bother checking for NOT NULL on columns that do not change */
+ continue;
+ }
+ onError = pTab->aCol[i].notNull;
+ if( onError==OE_None ) continue; /* This column is allowed to be NULL */
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+ if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
+ onError = OE_Abort;
+ }
+ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
+ || onError==OE_Ignore || onError==OE_Replace );
+ addr1 = 0;
+ switch( onError ){
+ case OE_Replace: {
+ assert( onError==OE_Replace );
+ addr1 = sqlite3VdbeMakeLabel(pParse);
+ sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
+ VdbeCoverage(v);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
+ sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
+ VdbeCoverage(v);
+ onError = OE_Abort;
+ /* Fall through into the OE_Abort case to generate code that runs
+ ** if both the input and the default value are NULL */
+ }
+ case OE_Abort:
+ sqlite3MayAbort(pParse);
+ /* Fall through */
+ case OE_Rollback:
+ case OE_Fail: {
+ char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
+ pTab->aCol[i].zName);
+ sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
+ regNewData+1+i);
+ sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
+ sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
+ VdbeCoverage(v);
+ if( addr1 ) sqlite3VdbeResolveLabel(v, addr1);
+ break;
+ }
+ default: {
+ assert( onError==OE_Ignore );
+ sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
+ VdbeCoverage(v);
+ break;
+ }
+ }
+ }
/* Test all CHECK constraints
*/
#ifndef SQLITE_OMIT_CHECK
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
@@ -1673,13 +1412,13 @@
sqlite3VdbeVerifyAbortable(v, onError);
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
sqlite3VdbeGoto(v, ignoreDest);
}else{
- char *zName = pCheck->a[i].zEName;
+ char *zName = pCheck->a[i].zName;
if( zName==0 ) zName = pTab->zName;
- if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */
+ if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
onError, zName, P4_TRANSIENT,
P5_ConstraintCheck);
}
sqlite3VdbeResolveLabel(v, allOk);
@@ -1730,54 +1469,10 @@
upsertJump = sqlite3VdbeAddOp0(v, OP_Goto);
VdbeComment((v, "UPSERT constraint goes first"));
}
}
- /* Determine if it is possible that triggers (either explicitly coded
- ** triggers or FK resolution actions) might run as a result of deletes
- ** that happen when OE_Replace conflict resolution occurs. (Call these
- ** "replace triggers".) If any replace triggers run, we will need to
- ** recheck all of the uniqueness constraints after they have all run.
- ** But on the recheck, the resolution is OE_Abort instead of OE_Replace.
- **
- ** If replace triggers are a possibility, then
- **
- ** (1) Allocate register regTrigCnt and initialize it to zero.
- ** That register will count the number of replace triggers that
- ** fire. Constraint recheck only occurs if the number is positive.
- ** (2) Initialize pTrigger to the list of all DELETE triggers on pTab.
- ** (3) Initialize addrRecheck and lblRecheckOk
- **
- ** The uniqueness rechecking code will create a series of tests to run
- ** in a second pass. The addrRecheck and lblRecheckOk variables are
- ** used to link together these tests which are separated from each other
- ** in the generate bytecode.
- */
- if( (db->flags & (SQLITE_RecTriggers|SQLITE_ForeignKeys))==0 ){
- /* There are not DELETE triggers nor FK constraints. No constraint
- ** rechecks are needed. */
- pTrigger = 0;
- regTrigCnt = 0;
- }else{
- if( db->flags&SQLITE_RecTriggers ){
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
- regTrigCnt = pTrigger!=0 || sqlite3FkRequired(pParse, pTab, 0, 0);
- }else{
- pTrigger = 0;
- regTrigCnt = sqlite3FkRequired(pParse, pTab, 0, 0);
- }
- if( regTrigCnt ){
- /* Replace triggers might exist. Allocate the counter and
- ** initialize it to zero. */
- regTrigCnt = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regTrigCnt);
- VdbeComment((v, "trigger count"));
- lblRecheckOk = sqlite3VdbeMakeLabel(pParse);
- addrRecheck = lblRecheckOk;
- }
- }
-
/* If rowid is changing, make sure the new rowid does not previously
** exist in the table.
*/
if( pkChng && pPk==0 ){
int addrRowidOk = sqlite3VdbeMakeLabel(pParse);
@@ -1863,16 +1558,18 @@
** REPLACE INTO t(rowid) VALUES($newrowid)
**
** to run without a statement journal if there are no indexes on the
** table.
*/
- if( regTrigCnt ){
+ Trigger *pTrigger = 0;
+ if( db->flags&SQLITE_RecTriggers ){
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+ }
+ if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
sqlite3MultiWrite(pParse);
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
regNewData, 1, 0, OE_Replace, 1, -1);
- sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */
- nReplaceTrig++;
}else{
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
assert( HasRowid(pTab) );
/* This OP_Delete opcode fires the pre-update-hook only. It does
** not modify the b-tree. It is more efficient to let the coming
@@ -1918,11 +1615,10 @@
for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){
int regIdx; /* Range of registers hold conent for pIdx */
int regR; /* Range of registers holding conflicting PK */
int iThisCur; /* Cursor for this UNIQUE index */
int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
- int addrConflictCk; /* First opcode in the conflict check logic */
if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
if( pUpIdx==pIdx ){
addrUniqueOk = upsertJump+1;
upsertBypass = sqlite3VdbeGoto(v, 0);
@@ -1958,29 +1654,27 @@
if( iField==XN_EXPR ){
pParse->iSelfTab = -(regNewData+1);
sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
pParse->iSelfTab = 0;
VdbeComment((v, "%s column %d", pIdx->zName, i));
- }else if( iField==XN_ROWID || iField==pTab->iPKey ){
- x = regNewData;
- sqlite3VdbeAddOp2(v, OP_IntCopy, x, regIdx+i);
- VdbeComment((v, "rowid"));
}else{
- testcase( sqlite3TableColumnToStorage(pTab, iField)!=iField );
- x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1;
- sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
- VdbeComment((v, "%s", pTab->aCol[iField].zName));
+ if( iField==XN_ROWID || iField==pTab->iPKey ){
+ x = regNewData;
+ }else{
+ x = iField + regNewData + 1;
+ }
+ sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i);
+ VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
VdbeComment((v, "for %s", pIdx->zName));
#ifdef SQLITE_ENABLE_NULL_TRIM
if( pIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
sqlite3SetMakeRecordP5(v, pIdx->pTable);
}
#endif
- sqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0);
/* In an UPDATE operation, if this index is the PRIMARY KEY index
** of a WITHOUT ROWID table and there has been no change the
** primary key, then no collision is possible. The collision detection
** logic below can all be skipped. */
@@ -2034,13 +1728,12 @@
}
#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */
/* Check to see if the new index entry will be unique */
sqlite3VdbeVerifyAbortable(v, onError);
- addrConflictCk =
- sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
- regIdx, pIdx->nKeyCol); VdbeCoverage(v);
+ sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
+ regIdx, pIdx->nKeyCol); VdbeCoverage(v);
/* Generate code to handle collisions */
regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
if( isUpdate || onError==OE_Replace ){
if( HasRowid(pTab) ){
@@ -2057,11 +1750,11 @@
/* Extract the PRIMARY KEY from the end of the index entry and
** store it in registers regR..regR+nPk-1 */
if( pIdx!=pPk ){
for(i=0; inKeyCol; i++){
assert( pPk->aiColumn[i]>=0 );
- x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]);
+ x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
VdbeComment((v, "%s.%s", pTab->zName,
pTab->aCol[pPk->aiColumn[i]].zName));
}
}
@@ -2083,11 +1776,10 @@
assert( x>=0 );
if( i==(pPk->nKeyCol-1) ){
addrJump = addrUniqueOk;
op = OP_Eq;
}
- x = sqlite3TableColumnToStorage(pTab, x);
sqlite3VdbeAddOp4(v, op,
regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverageIf(v, op==OP_Eq);
@@ -2120,75 +1812,21 @@
testcase( onError==OE_Ignore );
sqlite3VdbeGoto(v, ignoreDest);
break;
}
default: {
- int nConflictCk; /* Number of opcodes in conflict check logic */
-
+ Trigger *pTrigger = 0;
assert( onError==OE_Replace );
- nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
- assert( nConflictCk>0 );
- testcase( nConflictCk>1 );
- if( regTrigCnt ){
- sqlite3MultiWrite(pParse);
- nReplaceTrig++;
- }
- if( pTrigger && isUpdate ){
- sqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur);
+ if( db->flags&SQLITE_RecTriggers ){
+ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+ }
+ if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
+ sqlite3MultiWrite(pParse);
}
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
regR, nPkField, 0, OE_Replace,
(pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
- if( pTrigger && isUpdate ){
- sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur);
- }
- if( regTrigCnt ){
- int addrBypass; /* Jump destination to bypass recheck logic */
-
- sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */
- addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); /* Bypass recheck */
- VdbeComment((v, "bypass recheck"));
-
- /* Here we insert code that will be invoked after all constraint
- ** checks have run, if and only if one or more replace triggers
- ** fired. */
- sqlite3VdbeResolveLabel(v, lblRecheckOk);
- lblRecheckOk = sqlite3VdbeMakeLabel(pParse);
- if( pIdx->pPartIdxWhere ){
- /* Bypass the recheck if this partial index is not defined
- ** for the current row */
- sqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk);
- VdbeCoverage(v);
- }
- /* Copy the constraint check code from above, except change
- ** the constraint-ok jump destination to be the address of
- ** the next retest block */
- while( nConflictCk>0 ){
- VdbeOp x; /* Conflict check opcode to copy */
- /* The sqlite3VdbeAddOp4() call might reallocate the opcode array.
- ** Hence, make a complete copy of the opcode, rather than using
- ** a pointer to the opcode. */
- x = *sqlite3VdbeGetOp(v, addrConflictCk);
- if( x.opcode!=OP_IdxRowid ){
- int p2; /* New P2 value for copied conflict check opcode */
- if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){
- p2 = lblRecheckOk;
- }else{
- p2 = x.p2;
- }
- sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, x.p4.z, x.p4type);
- sqlite3VdbeChangeP5(v, x.p5);
- VdbeCoverageIf(v, p2!=x.p2);
- }
- nConflictCk--;
- addrConflictCk++;
- }
- /* If the retest fails, issue an abort */
- sqlite3UniqueConstraint(pParse, OE_Abort, pIdx);
-
- sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */
- }
seenReplace = 1;
break;
}
}
if( pUpIdx==pIdx ){
@@ -2205,40 +1843,10 @@
sqlite3VdbeGoto(v, ipkTop);
VdbeComment((v, "Do IPK REPLACE"));
sqlite3VdbeJumpHere(v, ipkBottom);
}
- /* Recheck all uniqueness constraints after replace triggers have run */
- testcase( regTrigCnt!=0 && nReplaceTrig==0 );
- assert( regTrigCnt!=0 || nReplaceTrig==0 );
- if( nReplaceTrig ){
- sqlite3VdbeAddOp2(v, OP_IfNot, regTrigCnt, lblRecheckOk);VdbeCoverage(v);
- if( !pPk ){
- if( isUpdate ){
- sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRecheck, regOldData);
- sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
- VdbeCoverage(v);
- }
- sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRecheck, regNewData);
- VdbeCoverage(v);
- sqlite3RowidConstraint(pParse, OE_Abort, pTab);
- }else{
- sqlite3VdbeGoto(v, addrRecheck);
- }
- sqlite3VdbeResolveLabel(v, lblRecheckOk);
- }
-
- /* Generate the table record */
- if( HasRowid(pTab) ){
- int regRec = aRegIdx[ix];
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec);
- sqlite3SetMakeRecordP5(v, pTab);
- if( !bAffinityDone ){
- sqlite3TableAffinity(v, pTab, 0);
- }
- }
-
*pbMayReplace = seenReplace;
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
#ifdef SQLITE_ENABLE_NULL_TRIM
@@ -2284,11 +1892,14 @@
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
Vdbe *v; /* Prepared statements under construction */
Index *pIdx; /* An index being inserted or updated */
u8 pik_flags; /* flag values passed to the btree insert */
+ int regData; /* Content registers (after the rowid) */
+ int regRec; /* Register holding assembled record for the table */
int i; /* Loop counter */
+ u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
assert( update_flags==0
|| update_flags==OPFLAG_ISUPDATE
|| update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
);
@@ -2295,15 +1906,12 @@
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- /* All REPLACE indexes are at the end of the list */
- assert( pIdx->onError!=OE_Replace
- || pIdx->pNext==0
- || pIdx->pNext->onError==OE_Replace );
if( aRegIdx[i]==0 ) continue;
+ bAffinityDone = 1;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
}
pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
@@ -2327,10 +1935,17 @@
aRegIdx[i]+1,
pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
sqlite3VdbeChangeP5(v, pik_flags);
}
if( !HasRowid(pTab) ) return;
+ regData = regNewData + 1;
+ regRec = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
+ sqlite3SetMakeRecordP5(v, pTab);
+ if( !bAffinityDone ){
+ sqlite3TableAffinity(v, pTab, 0);
+ }
if( pParse->nested ){
pik_flags = 0;
}else{
pik_flags = OPFLAG_NCHANGE;
pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
@@ -2339,11 +1954,11 @@
pik_flags |= OPFLAG_APPEND;
}
if( useSeekResult ){
pik_flags |= OPFLAG_USESEEKRESULT;
}
- sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
+ sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
if( !pParse->nested ){
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
sqlite3VdbeChangeP5(v, pik_flags);
}
@@ -2449,11 +2064,11 @@
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
assert( pDest && pSrc );
assert( pDest->pTable!=pSrc->pTable );
- if( pDest->nKeyCol!=pSrc->nKeyCol || pDest->nColumn!=pSrc->nColumn ){
+ if( pDest->nKeyCol!=pSrc->nKeyCol ){
return 0; /* Different number of columns */
}
if( pDest->onError!=pSrc->onError ){
return 0; /* Different conflict resolution strategies */
}
@@ -2626,43 +2241,10 @@
if( (db->mDbFlags & DBFLAG_Vacuum)==0
&& (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN
){
return 0; /* Neither table may have __hidden__ columns */
}
-#endif
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- /* Even if tables t1 and t2 have identical schemas, if they contain
- ** generated columns, then this statement is semantically incorrect:
- **
- ** INSERT INTO t2 SELECT * FROM t1;
- **
- ** The reason is that generated column values are returned by the
- ** the SELECT statement on the right but the INSERT statement on the
- ** left wants them to be omitted.
- **
- ** Nevertheless, this is a useful notational shorthand to tell SQLite
- ** to do a bulk transfer all of the content from t1 over to t2.
- **
- ** We could, in theory, disable this (except for internal use by the
- ** VACUUM command where it is actually needed). But why do that? It
- ** seems harmless enough, and provides a useful service.
- */
- if( (pDestCol->colFlags & COLFLAG_GENERATED) !=
- (pSrcCol->colFlags & COLFLAG_GENERATED) ){
- return 0; /* Both columns have the same generated-column type */
- }
- /* But the transfer is only allowed if both the source and destination
- ** tables have the exact same expressions for generated columns.
- ** This requirement could be relaxed for VIRTUAL columns, I suppose.
- */
- if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){
- if( sqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){
- testcase( pDestCol->colFlags & COLFLAG_VIRTUAL );
- testcase( pDestCol->colFlags & COLFLAG_STORED );
- return 0; /* Different generator expressions */
- }
- }
#endif
if( pDestCol->affinity!=pSrcCol->affinity ){
return 0; /* Affinity must be the same on all columns */
}
if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
@@ -2670,11 +2252,11 @@
}
if( pDestCol->notNull && !pSrcCol->notNull ){
return 0; /* tab2 must be NOT NULL if tab1 is */
}
/* Default values for second and subsequent columns need to match. */
- if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){
+ if( i>0 ){
assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0)
|| (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
pSrcCol->pDflt->u.zToken)!=0)
Index: src/loadext.c
==================================================================
--- src/loadext.c
+++ src/loadext.c
@@ -459,23 +459,11 @@
#else
0,
#endif
/* Version 3.28.0 and later */
sqlite3_stmt_isexplain,
- sqlite3_value_frombind,
- /* Version 3.30.0 and later */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3_drop_modules,
-#else
- 0,
-#endif
- /* Version 3.31.0 and later */
- sqlite3_hard_heap_limit64,
- sqlite3_uri_key,
- sqlite3_filename_database,
- sqlite3_filename_journal,
- sqlite3_filename_wal,
+ sqlite3_value_frombind
};
/*
** Attempt to load an SQLite extension library contained in the file
** zFile. The entry point is zProc. zProc may be 0 in which case a
Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -681,13 +681,10 @@
** the lookaside memory.
*/
static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
#ifndef SQLITE_OMIT_LOOKASIDE
void *pStart;
- sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt;
- int nBig; /* Number of full-size slots */
- int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */
if( sqlite3LookasideUsed(db,0)>0 ){
return SQLITE_BUSY;
}
/* Free any existing lookaside buffer for this handle before
@@ -706,75 +703,41 @@
if( sz==0 || cnt==0 ){
sz = 0;
pStart = 0;
}else if( pBuf==0 ){
sqlite3BeginBenignMalloc();
- pStart = sqlite3Malloc( szAlloc ); /* IMP: R-61949-35727 */
+ pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt ); /* IMP: R-61949-35727 */
sqlite3EndBenignMalloc();
- if( pStart ) szAlloc = sqlite3MallocSize(pStart);
+ if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
}else{
pStart = pBuf;
}
-#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
- if( sz>=LOOKASIDE_SMALL*3 ){
- nBig = szAlloc/(3*LOOKASIDE_SMALL+sz);
- nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL;
- }else if( sz>=LOOKASIDE_SMALL*2 ){
- nBig = szAlloc/(LOOKASIDE_SMALL+sz);
- nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL;
- }else
-#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
- if( sz>0 ){
- nBig = szAlloc/sz;
- nSm = 0;
- }else{
- nBig = nSm = 0;
- }
db->lookaside.pStart = pStart;
db->lookaside.pInit = 0;
db->lookaside.pFree = 0;
db->lookaside.sz = (u16)sz;
- db->lookaside.szTrue = (u16)sz;
if( pStart ){
int i;
LookasideSlot *p;
assert( sz > (int)sizeof(LookasideSlot*) );
+ db->lookaside.nSlot = cnt;
p = (LookasideSlot*)pStart;
- for(i=0; i=0; i--){
p->pNext = db->lookaside.pInit;
db->lookaside.pInit = p;
p = (LookasideSlot*)&((u8*)p)[sz];
}
-#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
- db->lookaside.pSmallInit = 0;
- db->lookaside.pSmallFree = 0;
- db->lookaside.pMiddle = p;
- for(i=0; ipNext = db->lookaside.pSmallInit;
- db->lookaside.pSmallInit = p;
- p = (LookasideSlot*)&((u8*)p)[LOOKASIDE_SMALL];
- }
-#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
- assert( ((uptr)p)<=szAlloc + (uptr)pStart );
db->lookaside.pEnd = p;
db->lookaside.bDisable = 0;
db->lookaside.bMalloced = pBuf==0 ?1:0;
- db->lookaside.nSlot = nBig+nSm;
}else{
db->lookaside.pStart = db;
-#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
- db->lookaside.pSmallInit = 0;
- db->lookaside.pSmallFree = 0;
- db->lookaside.pMiddle = db;
-#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
db->lookaside.pEnd = db;
db->lookaside.bDisable = 1;
- db->lookaside.sz = 0;
db->lookaside.bMalloced = 0;
db->lookaside.nSlot = 0;
}
- assert( sqlite3LookasideUsed(db,0)==0 );
#endif /* SQLITE_OMIT_LOOKASIDE */
return SQLITE_OK;
}
/*
@@ -871,25 +834,19 @@
int op; /* The opcode */
u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */
} aFlagOp[] = {
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
- { SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView },
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
{ SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
{ SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
{ SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
{ SQLITE_DBCONFIG_WRITABLE_SCHEMA, SQLITE_WriteSchema|
SQLITE_NoSchemaError },
- { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter },
- { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL },
- { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML },
- { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt },
- { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
for(i=0; i0 && z[n-1]==' ' ){ n--; }
+ return n==0;
+}
+
/*
** This is the default collating function named "BINARY" which is always
** available.
+**
+** If the padFlag argument is not NULL then space padding at the end
+** of strings is ignored. This implements the RTRIM collation.
*/
static int binCollFunc(
- void *NotUsed,
+ void *padFlag,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
int rc, n;
- UNUSED_PARAMETER(NotUsed);
n = nKey1xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 );
- return p==0 || p->xCmp==binCollFunc;
+ assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0
+ || strcmp(p->zName,"BINARY")==0 );
+ return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
}
/*
** Another built-in collating sequence: NOCASE.
**
@@ -1273,12 +1237,15 @@
}
sqlite3HashClear(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
Module *pMod = (Module *)sqliteHashData(i);
+ if( pMod->xDestroy ){
+ pMod->xDestroy(pMod->pAux);
+ }
sqlite3VtabEponymousTableClear(db, pMod);
- sqlite3VtabModuleUnref(db, pMod);
+ sqlite3DbFree(db, pMod);
}
sqlite3HashClear(&db->aModule);
#endif
sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */
@@ -1424,11 +1391,10 @@
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break;
case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break;
case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break;
- case SQLITE_CANTOPEN_SYMLINK: zName = "SQLITE_CANTOPEN_SYMLINK"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break;
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
@@ -1756,20 +1722,12 @@
){
return SQLITE_MISUSE_BKPT;
}
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
- assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
- extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
- SQLITE_SUBTYPE|SQLITE_INNOCUOUS);
+ extraFlags = enc & SQLITE_DETERMINISTIC;
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
-
- /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
- ** the meaning is inverted. So flip the bit. */
- assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS );
- extraFlags ^= SQLITE_FUNC_UNSAFE;
-
#ifndef SQLITE_OMIT_UTF16
/* If SQLITE_UTF16 is specified as the encoding type, transform this
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
@@ -1779,17 +1737,15 @@
*/
if( enc==SQLITE_UTF16 ){
enc = SQLITE_UTF16NATIVE;
}else if( enc==SQLITE_ANY ){
int rc;
- rc = sqlite3CreateFunc(db, zFunctionName, nArg,
- (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE,
+ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
if( rc==SQLITE_OK ){
- rc = sqlite3CreateFunc(db, zFunctionName, nArg,
- (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE,
- pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
+ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
+ pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
}
if( rc!=SQLITE_OK ){
return rc;
}
enc = SQLITE_UTF16BE;
@@ -1829,11 +1785,10 @@
pDestructor->nRef++;
}
p->u.pDestructor = pDestructor;
p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
- testcase( p->funcFlags & SQLITE_DIRECTONLY );
p->xSFunc = xSFunc ? xSFunc : xStep;
p->xFinalize = xFinal;
p->xValue = xValue;
p->xInverse = xInverse;
p->pUserData = pUserData;
@@ -3111,52 +3066,20 @@
db->errMask = 0xff;
db->nDb = 2;
db->magic = SQLITE_MAGIC_BUSY;
db->aDb = db->aDbStatic;
db->lookaside.bDisable = 1;
- db->lookaside.sz = 0;
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
db->autoCommit = 1;
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->nMaxSorterMmap = 0x7FFFFFFF;
- db->flags |= SQLITE_ShortColNames
- | SQLITE_EnableTrigger
- | SQLITE_EnableView
- | SQLITE_CacheSpill
-#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0
- | SQLITE_TrustedSchema
-#endif
-/* The SQLITE_DQS compile-time option determines the default settings
-** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
-**
-** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML
-** ---------- ----------------------- -----------------------
-** undefined on on
-** 3 on on
-** 2 on off
-** 1 off on
-** 0 off off
-**
-** Legacy behavior is 3 (double-quoted string literals are allowed anywhere)
-** and so that is the default. But developers are encouranged to use
-** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible.
-*/
-#if !defined(SQLITE_DQS)
-# define SQLITE_DQS 3
-#endif
-#if (SQLITE_DQS&1)==1
- | SQLITE_DqsDML
-#endif
-#if (SQLITE_DQS&2)==2
- | SQLITE_DqsDDL
-#endif
-
+ db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
#if SQLITE_DEFAULT_CKPTFULLFSYNC
| SQLITE_CkptFullFSync
@@ -3186,10 +3109,13 @@
| SQLITE_EnableQPSG
#endif
#if defined(SQLITE_DEFAULT_DEFENSIVE)
| SQLITE_Defensive
#endif
+#if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE)
+ | SQLITE_LegacyAlter
+#endif
;
sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3HashInit(&db->aModule);
#endif
@@ -3203,11 +3129,11 @@
*/
createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
- createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
+ createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
/* EVIDENCE-OF: R-08308-17224 The default collating function for all
** strings is BINARY.
@@ -3357,17 +3283,10 @@
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3StmtVtabInit(db);
}
#endif
-#ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
- /* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
- ** option gives access to internal functions by default.
- ** Testing use only!!! */
- db->mDbFlags |= DBFLAG_InternalFunc;
-#endif
-
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
** mode. Doing nothing at all also makes NORMAL the default.
*/
#ifdef SQLITE_DEFAULT_LOCKING_MODE
@@ -3882,42 +3801,19 @@
case SQLITE_TESTCTRL_PRNG_RESTORE: {
sqlite3PrngRestoreState();
break;
}
- /* sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, sqlite3 *db);
- **
- ** Control the seed for the pseudo-random number generator (PRNG) that
- ** is built into SQLite. Cases:
- **
- ** x!=0 && db!=0 Seed the PRNG to the current value of the
- ** schema cookie in the main database for db, or
- ** x if the schema cookie is zero. This case
- ** is convenient to use with database fuzzers
- ** as it allows the fuzzer some control over the
- ** the PRNG seed.
- **
- ** x!=0 && db==0 Seed the PRNG to the value of x.
- **
- ** x==0 && db==0 Revert to default behavior of using the
- ** xRandomness method on the primary VFS.
- **
- ** This test-control also resets the PRNG so that the new seed will
- ** be used for the next call to sqlite3_randomness().
+ /*
+ ** Reset the PRNG back to its uninitialized state. The next call
+ ** to sqlite3_randomness() will reseed the PRNG using a single call
+ ** to the xRandomness method of the default VFS.
*/
-#ifndef SQLITE_OMIT_WSD
- case SQLITE_TESTCTRL_PRNG_SEED: {
- int x = va_arg(ap, int);
- int y;
- sqlite3 *db = va_arg(ap, sqlite3*);
- assert( db==0 || db->aDb[0].pSchema!=0 );
- if( db && (y = db->aDb[0].pSchema->schema_cookie)!=0 ){ x = y; }
- sqlite3Config.iPrngSeed = x;
+ case SQLITE_TESTCTRL_PRNG_RESET: {
sqlite3_randomness(0,0);
break;
}
-#endif
/*
** sqlite3_test_control(BITVEC_TEST, size, program)
**
** Run a test against a Bitvec object of size. The program argument
@@ -4098,18 +3994,19 @@
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
break;
}
- /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
+ /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff);
**
- ** Toggle the ability to use internal functions on or off for
- ** the database connection given in the argument.
+ ** If parameter onoff is non-zero, internal-use-only SQL functions
+ ** are visible to ordinary SQL. This is useful for testing but is
+ ** unsafe because invalid parameters to those internal-use-only functions
+ ** can result in crashes or segfaults.
*/
case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
- sqlite3 *db = va_arg(ap, sqlite3*);
- db->mDbFlags ^= DBFLAG_InternalFunc;
+ sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int);
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
**
@@ -4122,21 +4019,10 @@
case SQLITE_TESTCTRL_NEVER_CORRUPT: {
sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int);
break;
}
- /* sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int);
- **
- ** Set or clear a flag that causes SQLite to verify that type, name,
- ** and tbl_name fields of the sqlite_master table. This is normally
- ** on, but it is sometimes useful to turn it off for testing.
- */
- case SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS: {
- sqlite3GlobalConfig.bExtraSchemaChecks = va_arg(ap, int);
- break;
- }
-
/* Set the threshold at which OP_Once counters reset back to zero.
** By default this is 0x7ffffffe (over 2 billion), but that value is
** too big to test in a reasonable amount of time, so this control is
** provided to set a small and easily reachable reset value.
*/
@@ -4219,26 +4105,10 @@
FILE *out = va_arg(ap, FILE*);
if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
break;
}
#endif /* defined(YYCOVERAGE) */
-
- /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
- **
- ** This test-control causes the most recent sqlite3_result_int64() value
- ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally,
- ** MEM_IntReal values only arise during an INSERT operation of integer
- ** values into a REAL column, so they can be challenging to test. This
- ** test-control enables us to write an intreal() SQL function that can
- ** inject an intreal() value at arbitrary places in an SQL statement,
- ** for testing purposes.
- */
- case SQLITE_TESTCTRL_RESULT_INTREAL: {
- sqlite3_context *pCtx = va_arg(ap, sqlite3_context*);
- sqlite3ResultIntReal(pCtx);
- break;
- }
}
va_end(ap);
#endif /* SQLITE_UNTESTABLE */
return rc;
}
@@ -4264,23 +4134,10 @@
zFilename += sqlite3Strlen30(zFilename) + 1;
}
return 0;
}
-/*
-** Return a pointer to the name of Nth query parameter of the filename.
-*/
-const char *sqlite3_uri_key(const char *zFilename, int N){
- if( zFilename==0 || N<0 ) return 0;
- zFilename += sqlite3Strlen30(zFilename) + 1;
- while( zFilename[0] && (N--)>0 ){
- zFilename += sqlite3Strlen30(zFilename) + 1;
- zFilename += sqlite3Strlen30(zFilename) + 1;
- }
- return zFilename[0] ? zFilename : 0;
-}
-
/*
** Return a boolean value for a query parameter.
*/
int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
@@ -4302,50 +4159,10 @@
bDflt = v;
}
return bDflt;
}
-/*
-** The Pager stores the Journal filename, WAL filename, and Database filename
-** consecutively in memory, in that order, with prefixes \000\001\000,
-** \002\000, and \003\000, in that order. Thus the three names look like query
-** parameters if you start at the first prefix.
-**
-** This routine backs up a filename to the start of the first prefix.
-**
-** This only works if the filenamed passed in was obtained from the Pager.
-*/
-static const char *startOfNameList(const char *zName){
- while( zName[0]!='\001' || zName[1]!=0 ){
- zName -= 3;
- while( zName[0]!='\000' ){ zName--; }
- zName++;
- }
- return zName-1;
-}
-
-/*
-** Translate a filename that was handed to a VFS routine into the corresponding
-** database, journal, or WAL file.
-**
-** It is an error to pass this routine a filename string that was not
-** passed into the VFS from the SQLite core. Doing so is similar to
-** passing free() a pointer that was not obtained from malloc() - it is
-** an error that we cannot easily detect but that will likely cause memory
-** corruption.
-*/
-const char *sqlite3_filename_database(const char *zFilename){
- return sqlite3_uri_parameter(zFilename - 3, "\003");
-}
-const char *sqlite3_filename_journal(const char *zFilename){
- const char *z = sqlite3_uri_parameter(startOfNameList(zFilename), "\001");
- return ALWAYS(z) && z[0] ? z : 0;
-}
-const char *sqlite3_filename_wal(const char *zFilename){
- return sqlite3_uri_parameter(startOfNameList(zFilename), "\002");
-}
-
/*
** Return the Btree pointer identified by zDbName. Return NULL if not found.
*/
Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
Index: src/malloc.c
==================================================================
--- src/malloc.c
+++ src/malloc.c
@@ -30,31 +30,23 @@
UNUSED_PARAMETER(n);
return 0;
#endif
}
-/*
-** Default value of the hard heap limit. 0 means "no limit".
-*/
-#ifndef SQLITE_MAX_MEMORY
-# define SQLITE_MAX_MEMORY 0
-#endif
-
/*
** State information local to the memory allocation subsystem.
*/
static SQLITE_WSD struct Mem0Global {
sqlite3_mutex *mutex; /* Mutex to serialize access */
sqlite3_int64 alarmThreshold; /* The soft heap limit */
- sqlite3_int64 hardLimit; /* The hard upper bound on memory */
/*
** True if heap is nearly "full" where "full" is defined by the
** sqlite3_soft_heap_limit() setting.
*/
int nearlyFull;
-} mem0 = { 0, SQLITE_MAX_MEMORY, SQLITE_MAX_MEMORY, 0 };
+} mem0 = { 0, 0, 0 };
#define mem0 GLOBAL(struct Mem0Global, mem0)
/*
** Return the memory allocator mutex. sqlite3_status() needs it.
@@ -80,19 +72,12 @@
return SQLITE_OK;
}
#endif
/*
-** Set the soft heap-size limit for the library. An argument of
-** zero disables the limit. A negative argument is a no-op used to
-** obtain the return value.
-**
-** The return value is the value of the heap limit just before this
-** interface was called.
-**
-** If the hard heap limit is enabled, then the soft heap limit cannot
-** be disabled nor raised above the hard heap limit.
+** Set the soft heap-size limit for the library. Passing a zero or
+** negative value indicates no limit.
*/
sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
sqlite3_int64 excess;
sqlite3_int64 nUsed;
@@ -104,13 +89,10 @@
priorLimit = mem0.alarmThreshold;
if( n<0 ){
sqlite3_mutex_leave(mem0.mutex);
return priorLimit;
}
- if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
- n = mem0.hardLimit;
- }
mem0.alarmThreshold = n;
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
mem0.nearlyFull = (n>0 && n<=nUsed);
sqlite3_mutex_leave(mem0.mutex);
excess = sqlite3_memory_used() - n;
@@ -119,41 +101,10 @@
}
void sqlite3_soft_heap_limit(int n){
if( n<0 ) n = 0;
sqlite3_soft_heap_limit64(n);
}
-
-/*
-** Set the hard heap-size limit for the library. An argument of zero
-** disables the hard heap limit. A negative argument is a no-op used
-** to obtain the return value without affecting the hard heap limit.
-**
-** The return value is the value of the hard heap limit just prior to
-** calling this interface.
-**
-** Setting the hard heap limit will also activate the soft heap limit
-** and constrain the soft heap limit to be no more than the hard heap
-** limit.
-*/
-sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){
- sqlite3_int64 priorLimit;
-#ifndef SQLITE_OMIT_AUTOINIT
- int rc = sqlite3_initialize();
- if( rc ) return -1;
-#endif
- sqlite3_mutex_enter(mem0.mutex);
- priorLimit = mem0.hardLimit;
- if( n>=0 ){
- mem0.hardLimit = n;
- if( nSQLITE_MAX_MEMORY ){
+ *pp = 0;
+ return;
+ }
+#endif
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
mem0.nearlyFull = 1;
sqlite3MallocAlarm(nFull);
- if( mem0.hardLimit ){
- nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- if( nUsed >= mem0.hardLimit - nFull ){
- *pp = 0;
- return;
- }
- }
}else{
mem0.nearlyFull = 0;
}
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
@@ -330,45 +281,27 @@
*/
int sqlite3MallocSize(void *p){
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return sqlite3GlobalConfig.m.xSize(p);
}
-static int lookasideMallocSize(sqlite3 *db, void *p){
-#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
- return plookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL;
-#else
- return db->lookaside.szTrue;
-#endif
-}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
assert( p!=0 );
-#ifdef SQLITE_DEBUG
if( db==0 || !isLookaside(db,p) ){
+#ifdef SQLITE_DEBUG
if( db==0 ){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
}
- }
-#endif
- if( db ){
- if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){
-#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
- if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){
- assert( sqlite3_mutex_held(db->mutex) );
- return LOOKASIDE_SMALL;
- }
-#endif
- if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){
- assert( sqlite3_mutex_held(db->mutex) );
- return db->lookaside.szTrue;
- }
- }
- }
- return sqlite3GlobalConfig.m.xSize(p);
+#endif
+ return sqlite3GlobalConfig.m.xSize(p);
+ }else{
+ assert( sqlite3_mutex_held(db->mutex) );
+ return db->lookaside.sz;
+ }
}
sqlite3_uint64 sqlite3_msize(void *p){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
@@ -411,31 +344,19 @@
if( db ){
if( db->pnBytesFreed ){
measureAllocationSize(db, p);
return;
}
- if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){
-#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
- if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){
- LookasideSlot *pBuf = (LookasideSlot*)p;
-#ifdef SQLITE_DEBUG
- memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */
-#endif
- pBuf->pNext = db->lookaside.pSmallFree;
- db->lookaside.pSmallFree = pBuf;
- return;
- }
-#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
- if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){
- LookasideSlot *pBuf = (LookasideSlot*)p;
-#ifdef SQLITE_DEBUG
- memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */
-#endif
- pBuf->pNext = db->lookaside.pFree;
- db->lookaside.pFree = pBuf;
- return;
- }
+ if( isLookaside(db, p) ){
+ LookasideSlot *pBuf = (LookasideSlot*)p;
+#ifdef SQLITE_DEBUG
+ /* Trash all content in the buffer being freed */
+ memset(p, 0xaa, db->lookaside.sz);
+#endif
+ pBuf->pNext = db->lookaside.pFree;
+ db->lookaside.pFree = pBuf;
+ return;
}
}
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
@@ -587,41 +508,27 @@
#ifndef SQLITE_OMIT_LOOKASIDE
LookasideSlot *pBuf;
assert( db!=0 );
assert( sqlite3_mutex_held(db->mutex) );
assert( db->pnBytesFreed==0 );
- if( n>db->lookaside.sz ){
- if( !db->lookaside.bDisable ){
- db->lookaside.anStat[1]++;
- }else if( db->mallocFailed ){
- return 0;
- }
- return dbMallocRawFinish(db, n);
- }
-#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
- if( n<=LOOKASIDE_SMALL ){
- if( (pBuf = db->lookaside.pSmallFree)!=0 ){
- db->lookaside.pSmallFree = pBuf->pNext;
- db->lookaside.anStat[0]++;
- return (void*)pBuf;
- }else if( (pBuf = db->lookaside.pSmallInit)!=0 ){
- db->lookaside.pSmallInit = pBuf->pNext;
- db->lookaside.anStat[0]++;
- return (void*)pBuf;
- }
- }
-#endif
- if( (pBuf = db->lookaside.pFree)!=0 ){
- db->lookaside.pFree = pBuf->pNext;
- db->lookaside.anStat[0]++;
- return (void*)pBuf;
- }else if( (pBuf = db->lookaside.pInit)!=0 ){
- db->lookaside.pInit = pBuf->pNext;
- db->lookaside.anStat[0]++;
- return (void*)pBuf;
- }else{
- db->lookaside.anStat[2]++;
+ if( db->lookaside.bDisable==0 ){
+ assert( db->mallocFailed==0 );
+ if( n>db->lookaside.sz ){
+ db->lookaside.anStat[1]++;
+ }else if( (pBuf = db->lookaside.pFree)!=0 ){
+ db->lookaside.pFree = pBuf->pNext;
+ db->lookaside.anStat[0]++;
+ return (void*)pBuf;
+ }else if( (pBuf = db->lookaside.pInit)!=0 ){
+ db->lookaside.pInit = pBuf->pNext;
+ db->lookaside.anStat[0]++;
+ return (void*)pBuf;
+ }else{
+ db->lookaside.anStat[2]++;
+ }
+ }else if( db->mallocFailed ){
+ return 0;
}
#else
assert( db!=0 );
assert( sqlite3_mutex_held(db->mutex) );
assert( db->pnBytesFreed==0 );
@@ -641,20 +548,11 @@
*/
void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
assert( db!=0 );
if( p==0 ) return sqlite3DbMallocRawNN(db, n);
assert( sqlite3_mutex_held(db->mutex) );
- if( ((uptr)p)<(uptr)db->lookaside.pEnd ){
-#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
- if( ((uptr)p)>=(uptr)db->lookaside.pMiddle ){
- if( n<=LOOKASIDE_SMALL ) return p;
- }else
-#endif
- if( ((uptr)p)>=(uptr)db->lookaside.pStart ){
- if( n<=db->lookaside.szTrue ) return p;
- }
- }
+ if( isLookaside(db,p) && n<=db->lookaside.sz ) return p;
return dbReallocFinish(db, p, n);
}
static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
void *pNew = 0;
assert( db!=0 );
@@ -661,11 +559,11 @@
assert( p!=0 );
if( db->mallocFailed==0 ){
if( isLookaside(db, p) ){
pNew = sqlite3DbMallocRawNN(db, n);
if( pNew ){
- memcpy(pNew, p, lookasideMallocSize(db, p));
+ memcpy(pNew, p, db->lookaside.sz);
sqlite3DbFree(db, p);
}
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
@@ -760,11 +658,11 @@
if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
db->mallocFailed = 1;
if( db->nVdbeExec>0 ){
db->u1.isInterrupted = 1;
}
- DisableLookaside;
+ db->lookaside.bDisable++;
if( db->pParse ){
db->pParse->rc = SQLITE_NOMEM_BKPT;
}
}
}
@@ -779,11 +677,11 @@
void sqlite3OomClear(sqlite3 *db){
if( db->mallocFailed && db->nVdbeExec==0 ){
db->mallocFailed = 0;
db->u1.isInterrupted = 0;
assert( db->lookaside.bDisable>0 );
- EnableLookaside;
+ db->lookaside.bDisable--;
}
}
/*
** Take actions at the end of an API call to indicate an OOM error
Index: src/memjournal.c
==================================================================
--- src/memjournal.c
+++ src/memjournal.c
@@ -94,13 +94,18 @@
u8 *zOut = zBuf;
int nRead = iAmt;
int iChunkOffset;
FileChunk *pChunk;
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
if( (iAmt+iOfst)>p->endpoint.iOffset ){
return SQLITE_IOERR_SHORT_READ;
}
+#endif
+
+ assert( (iAmt+iOfst)<=p->endpoint.iOffset );
assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
sqlite3_int64 iOff = 0;
for(pChunk=p->pFirst;
ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
Index: src/msvc.h
==================================================================
--- src/msvc.h
+++ src/msvc.h
@@ -31,11 +31,6 @@
#pragma warning(disable : 4306)
#pragma warning(disable : 4702)
#pragma warning(disable : 4706)
#endif /* defined(_MSC_VER) */
-#if defined(_MSC_VER) && !defined(_WIN64)
-#undef SQLITE_4_BYTE_ALIGNED_MALLOC
-#define SQLITE_4_BYTE_ALIGNED_MALLOC
-#endif /* defined(_MSC_VER) && !defined(_WIN64) */
-
#endif /* SQLITE_MSVC_H */
Index: src/mutex.h
==================================================================
--- src/mutex.h
+++ src/mutex.h
@@ -65,7 +65,6 @@
#define sqlite3MutexInit() SQLITE_OK
#define sqlite3MutexEnd()
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X) X
-int sqlite3_mutex_held(sqlite3_mutex*);
#endif /* defined(SQLITE_MUTEX_OMIT) */
Index: src/os.c
==================================================================
--- src/os.c
+++ src/os.c
@@ -213,11 +213,11 @@
DO_OS_MALLOC_TEST(0);
/* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
** reaching the VFS. */
- rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut);
+ rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
assert( rc==SQLITE_OK || pFile->pMethods==0 );
return rc;
}
int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
DO_OS_MALLOC_TEST(0);
@@ -256,19 +256,11 @@
void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
pVfs->xDlClose(pVfs, pHandle);
}
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
- if( sqlite3Config.iPrngSeed ){
- memset(zBufOut, 0, nByte);
- if( ALWAYS(nByte>(signed)sizeof(unsigned)) ) nByte = sizeof(unsigned int);
- memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte);
- return SQLITE_OK;
- }else{
- return pVfs->xRandomness(pVfs, nByte, zBufOut);
- }
-
+ return pVfs->xRandomness(pVfs, nByte, zBufOut);
}
int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
return pVfs->xSleep(pVfs, nMicro);
}
int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
Index: src/os_unix.c
==================================================================
--- src/os_unix.c
+++ src/os_unix.c
@@ -103,33 +103,17 @@
# include
# include
# include
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-/*
-** Try to determine if gethostuuid() is available based on standard
-** macros. This might sometimes compute the wrong value for some
-** obscure platforms. For those cases, simply compile with one of
-** the following:
-**
-** -DHAVE_GETHOSTUUID=0
-** -DHAVE_GETHOSTUUID=1
-**
-** None if this matters except when building on Apple products with
-** -DSQLITE_ENABLE_LOCKING_STYLE.
-*/
-#ifndef HAVE_GETHOSTUUID
-# define HAVE_GETHOSTUUID 0
-# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
- (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
-# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
- && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
-# undef HAVE_GETHOSTUUID
-# define HAVE_GETHOSTUUID 1
-# else
-# warning "gethostuuid() is disabled."
-# endif
+#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
+ (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
+# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
+ && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
+# define HAVE_GETHOSTUUID 1
+# else
+# warning "gethostuuid() is disabled."
# endif
#endif
#if OS_VXWORKS
@@ -535,18 +519,17 @@
#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
# ifdef __ANDROID__
{ "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 },
-#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
# else
{ "ioctl", (sqlite3_syscall_ptr)ioctl, 0 },
-#define osIoctl ((int(*)(int,unsigned long,...))aSyscall[28].pCurrent)
# endif
#else
{ "ioctl", (sqlite3_syscall_ptr)0, 0 },
#endif
+#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
}; /* End of the overrideable system calls */
/*
@@ -3683,11 +3666,11 @@
zDirname[ii] = '\0';
}else{
if( zDirname[0]!='/' ) zDirname[0] = '.';
zDirname[1] = 0;
}
- fd = robust_open(zDirname, O_RDONLY|O_BINARY|O_NOFOLLOW, 0);
+ fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
if( fd>=0 ){
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
}
*pFd = fd;
if( fd>=0 ) return SQLITE_OK;
@@ -4574,16 +4557,14 @@
}
}
if( pInode->bProcessLock==0 ){
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
- (sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
}
if( pShmNode->hShm<0 ){
- pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW,
- (sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
if( pShmNode->hShm<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
goto shm_open_err;
}
pShmNode->isReadonly = 1;
@@ -5786,11 +5767,10 @@
}
if( pInode ){
UnixUnusedFd **pp;
assert( sqlite3_mutex_notheld(pInode->pLockMutex) );
sqlite3_mutex_enter(pInode->pLockMutex);
- flags &= (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE);
for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
pUnused = *pp;
if( pUnused ){
*pp = pUnused->pNext;
}
@@ -5840,11 +5820,11 @@
** as the associated database file.
**
** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
** original filename is unavailable. But 8_3_NAMES is only used for
** FAT filesystems and permissions do not matter there, so just use
-** the default permissions. In 8_3_NAMES mode, leave *pMode set to zero.
+** the default permissions.
*/
static int findCreateFileMode(
const char *zPath, /* Path of file (possibly) being created */
int flags, /* Flags passed as 4th argument to xOpen() */
mode_t *pMode, /* OUT: Permissions to open file with */
@@ -5929,11 +5909,11 @@
int *pOutFlags /* Output flags returned to SQLite core */
){
unixFile *p = (unixFile *)pFile;
int fd = -1; /* File descriptor returned by open() */
int openFlags = 0; /* Flags to pass to open() */
- int eType = flags&0x0FFF00; /* Type of file to open */
+ int eType = flags&0xFFFFFF00; /* Type of file to open */
int noLock; /* True to omit locking primitives */
int rc = SQLITE_OK; /* Function Return Code */
int ctrlFlags = 0; /* UNIXFILE_* flags */
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
@@ -6039,11 +6019,11 @@
** 'conch file' locking functions later on. */
if( isReadonly ) openFlags |= O_RDONLY;
if( isReadWrite ) openFlags |= O_RDWR;
if( isCreate ) openFlags |= O_CREAT;
if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
- openFlags |= (O_LARGEFILE|O_BINARY|O_NOFOLLOW);
+ openFlags |= (O_LARGEFILE|O_BINARY);
if( fd<0 ){
mode_t openMode; /* Permissions to create file with */
uid_t uid; /* Userid for the file */
gid_t gid; /* Groupid for the file */
@@ -6075,23 +6055,15 @@
int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
if( rc==SQLITE_OK ) rc = rc2;
goto open_finished;
}
- /* The owner of the rollback journal or WAL file should always be the
- ** same as the owner of the database file. Try to ensure that this is
- ** the case. The chown() system call will be a no-op if the current
- ** process lacks root privileges, be we should at least try. Without
- ** this step, if a root process opens a database file, it can leave
- ** behinds a journal/WAL that is owned by root and hence make the
- ** database inaccessible to unprivileged processes.
- **
- ** If openMode==0, then that means uid and gid are not set correctly
- ** (probably because SQLite is configured to use 8+3 filename mode) and
- ** in that case we do not want to attempt the chown().
+ /* If this process is running as root and if creating a new rollback
+ ** journal or WAL file, set the ownership of the journal or WAL to be
+ ** the same as the original database.
*/
- if( openMode && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL))!=0 ){
+ if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
robustFchown(fd, uid, gid);
}
}
assert( fd>=0 );
if( pOutFlags ){
@@ -6098,12 +6070,11 @@
*pOutFlags = flags;
}
if( p->pPreallocatedUnused ){
p->pPreallocatedUnused->fd = fd;
- p->pPreallocatedUnused->flags =
- flags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE);
+ p->pPreallocatedUnused->flags = flags;
}
if( isDelete ){
#if OS_VXWORKS
zPath = zName;
@@ -6257,12 +6228,11 @@
** two of them are actually used */
assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
if( flags==SQLITE_ACCESS_EXISTS ){
struct stat buf;
- *pResOut = 0==osStat(zPath, &buf) &&
- (!S_ISREG(buf.st_mode) || buf.st_size>0);
+ *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
}else{
*pResOut = osAccess(zPath, W_OK|R_OK)==0;
}
return SQLITE_OK;
}
@@ -6312,11 +6282,11 @@
#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
return mkFullPathname(zPath, zOut, nOut);
#else
int rc = SQLITE_OK;
int nByte;
- int nLink = 0; /* Number of symbolic links followed so far */
+ int nLink = 1; /* Number of symbolic links followed so far */
const char *zIn = zPath; /* Input path for each iteration of loop */
char *zDel = 0;
assert( pVfs->mxPathname==MAX_PATHNAME );
UNUSED_PARAMETER(pVfs);
@@ -6341,15 +6311,14 @@
}else{
bLink = S_ISLNK(buf.st_mode);
}
if( bLink ){
- nLink++;
if( zDel==0 ){
zDel = sqlite3_malloc(nOut);
if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
- }else if( nLink>=SQLITE_MAX_SYMLINKS ){
+ }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
rc = SQLITE_CANTOPEN_BKPT;
}
if( rc==SQLITE_OK ){
nByte = osReadlink(zIn, zDel, nOut-1);
@@ -6381,11 +6350,10 @@
if( bLink==0 ) break;
zIn = zOut;
}while( rc==SQLITE_OK );
sqlite3_free(zDel);
- if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
return rc;
#endif /* HAVE_READLINK && HAVE_LSTAT */
}
@@ -6867,11 +6835,11 @@
int islockfile /* if non zero missing dirs will be created */
) {
int fd = -1;
unixFile *pNew;
int rc = SQLITE_OK;
- int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW;
+ int openFlags = O_RDWR | O_CREAT;
sqlite3_vfs dummyVfs;
int terrno = 0;
UnixUnusedFd *pUnused = NULL;
/* 1. first try to open/create the file
@@ -6897,11 +6865,11 @@
fd = robust_open(path, openFlags, 0);
}
}
}
if( fd<0 ){
- openFlags = O_RDONLY | O_NOFOLLOW;
+ openFlags = O_RDONLY;
fd = robust_open(path, openFlags, 0);
terrno = errno;
}
if( fd<0 ){
if( islockfile ){
@@ -6948,11 +6916,11 @@
int sqlite3_hostid_num = 0;
#endif
#define PROXY_HOSTIDLEN 16 /* conch file host id length */
-#if HAVE_GETHOSTUUID
+#ifdef HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
#endif
/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
@@ -6959,11 +6927,11 @@
** bytes of writable memory.
*/
static int proxyGetHostID(unsigned char *pHostID, int *pError){
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
memset(pHostID, 0, PROXY_HOSTIDLEN);
-#if HAVE_GETHOSTUUID
+#ifdef HAVE_GETHOSTUUID
{
struct timespec timeout = {1, 0}; /* 1 sec timeout */
if( gethostuuid(pHostID, &timeout) ){
int err = errno;
if( pError ){
@@ -7023,11 +6991,11 @@
if( readLenpShm;
- assert( pShm!=0 );
}
pShmNode = pShm->pShmNode;
sqlite3_mutex_enter(pShmNode->mutex);
if( pShmNode->isUnlocked ){
@@ -4516,11 +4515,10 @@
osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
return rc;
}
}
if( pFd->mmapSize >= iOff+nAmt ){
- assert( pFd->pMapRegion!=0 );
*pp = &((u8 *)pFd->pMapRegion)[iOff];
pFd->nFetchOut++;
}
}
#endif
Index: src/pager.c
==================================================================
--- src/pager.c
+++ src/pager.c
@@ -1170,11 +1170,10 @@
if( pPager->eLock!=UNKNOWN_LOCK ){
pPager->eLock = (u8)eLock;
}
IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
}
- pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */
return rc;
}
/*
** Lock the database file to level eLock, which must be either SHARED_LOCK,
@@ -1358,11 +1357,10 @@
** master-journal filename.
*/
len = 0;
}
zMaster[len] = '\0';
- zMaster[len+1] = '\0';
return SQLITE_OK;
}
/*
@@ -1892,10 +1890,11 @@
/* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here
** without clearing the error code. This is intentional - the error
** code is cleared and the cache reset in the block below.
*/
assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
+ pPager->changeCountDone = 0;
pPager->eState = PAGER_OPEN;
}
/* If Pager.errCode is set, the contents of the pager cache cannot be
** trusted. Now that there are no outstanding references to the pager,
@@ -2155,10 +2154,11 @@
if( !pPager->exclusiveMode
&& (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
){
rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
+ pPager->changeCountDone = 0;
}
pPager->eState = PAGER_READER;
pPager->setMaster = 0;
return (rc==SQLITE_OK?rc2:rc);
@@ -2593,20 +2593,19 @@
** journal files extracted from regular rollback-journals.
*/
rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
if( rc!=SQLITE_OK ) goto delmaster_out;
nMasterPtr = pVfs->mxPathname+1;
- zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 2);
+ zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
if( !zMasterJournal ){
rc = SQLITE_NOMEM_BKPT;
goto delmaster_out;
}
- zMasterPtr = &zMasterJournal[nMasterJournal+2];
+ zMasterPtr = &zMasterJournal[nMasterJournal+1];
rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
if( rc!=SQLITE_OK ) goto delmaster_out;
zMasterJournal[nMasterJournal] = 0;
- zMasterJournal[nMasterJournal+1] = 0;
zJournal = zMasterJournal;
while( (zJournal-zMasterJournal)=1 );
+ nUri = (int)(&z[1] - zUri);
+ assert( nUri>=0 );
if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
/* This branch is taken when the journal path required by
** the database being opened will be more than pVfs->mxPathname
** bytes in length. This means the database cannot be opened,
** as it will not be possible to open the journal file or even
@@ -4836,92 +4824,54 @@
** Pager object (sizeof(Pager) bytes)
** PCache object (sqlite3PcacheSize() bytes)
** Database file handle (pVfs->szOsFile bytes)
** Sub-journal file handle (journalFileSize bytes)
** Main journal file handle (journalFileSize bytes)
- ** \0\1\0 journal prefix (3 bytes)
- ** Journal filename (nPathname+8+1 bytes)
- ** \2\0 WAL prefix (2 bytes)
- ** WAL filename (nPathname+4+1 bytes)
- ** \3\0 database prefix (2 bytes)
** Database file name (nPathname+1 bytes)
- ** URI query parameters (nUriByte bytes)
- ** \0\0 terminator (2 bytes)
+ ** Journal file name (nPathname+8+1 bytes)
*/
pPtr = (u8 *)sqlite3MallocZero(
- ROUND8(sizeof(*pPager)) + /* Pager structure */
- ROUND8(pcacheSize) + /* PCache object */
- ROUND8(pVfs->szOsFile) + /* The main db file */
- journalFileSize * 2 + /* The two journal files */
- 3 + /* Journal prefix */
- nPathname + 8 + 1 + /* Journal filename */
+ ROUND8(sizeof(*pPager)) + /* Pager structure */
+ ROUND8(pcacheSize) + /* PCache object */
+ ROUND8(pVfs->szOsFile) + /* The main db file */
+ journalFileSize * 2 + /* The two journal files */
+ nPathname + 1 + nUri + /* zFilename */
+ nPathname + 8 + 2 /* zJournal */
#ifndef SQLITE_OMIT_WAL
- 2 + /* WAL prefix */
- nPathname + 4 + 1 + /* WAL filename */
+ + nPathname + 4 + 2 /* zWal */
#endif
- 2 + /* Database prefix */
- nPathname + 1 + /* database filename */
- nUriByte + /* query parameters */
- 2 /* Terminator */
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
return SQLITE_NOMEM_BKPT;
}
- pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager));
- pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
- pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
- pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
- pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
+ pPager = (Pager*)(pPtr);
+ pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
+ pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
+ pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
+ pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize);
+ pPager->zFilename = (char*)(pPtr += journalFileSize);
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
-
- /* Fill in Pager.zJournal */
- pPtr[1] = '\001'; pPtr += 3;
- if( nPathname>0 ){
- pPager->zJournal = (char*)pPtr;
- memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
- memcpy(pPtr, "-journal",8); pPtr += 8 + 1;
-#ifdef SQLITE_ENABLE_8_3_NAMES
- sqlite3FileSuffix3(zFilename,pPager->zJournal);
- pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1);
-#endif
- }else{
- pPager->zJournal = 0;
- pPtr++;
- }
-
+ /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
+ if( zPathname ){
+ assert( nPathname>0 );
+ pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri);
+ memcpy(pPager->zFilename, zPathname, nPathname);
+ if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
+ memcpy(pPager->zJournal, zPathname, nPathname);
+ memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
+ sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
- /* Fill in Pager.zWal */
- pPtr[0] = '\002'; pPtr[1] = 0; pPtr += 2;
- if( nPathname>0 ){
- pPager->zWal = (char*)pPtr;
- memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
- memcpy(pPtr, "-wal", 4); pPtr += 4 + 1;
-#ifdef SQLITE_ENABLE_8_3_NAMES
- sqlite3FileSuffix3(zFilename, pPager->zWal);
- pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1);
-#endif
- }else{
- pPager->zWal = 0;
- pPtr++;
- }
-#endif
-
- /* Fill in the Pager.zFilename and pPager.zQueryParam fields */
- pPtr[0] = '\003'; pPtr[1] = 0; pPtr += 2;
- pPager->zFilename = (char*)pPtr;
- if( nPathname>0 ){
- memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1;
- if( zUri ){
- memcpy(pPtr, zUri, nUriByte); /* pPtr += nUriByte; // not needed */
- }
- /* Double-zero terminator implied by the sqlite3MallocZero */
- }
-
- if( nPathname ) sqlite3DbFree(0, zPathname);
+ pPager->zWal = &pPager->zJournal[nPathname+8+1];
+ memcpy(pPager->zWal, zPathname, nPathname);
+ memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
+ sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
+#endif
+ sqlite3DbFree(0, zPathname);
+ }
pPager->pVfs = pVfs;
pPager->vfsFlags = vfsFlags;
/* Open the pager file.
*/
@@ -4966,13 +4916,13 @@
}
}
}
#endif
}
- pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0);
+ pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
- || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){
+ || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
vfsFlags |= SQLITE_OPEN_READONLY;
goto act_like_temp_file;
}
}
}else{
@@ -6659,11 +6609,10 @@
/* This routine should not be called if a prior error has occurred.
** But if (due to a coding error elsewhere in the system) it does get
** called, just return the same error code without doing anything. */
if( NEVER(pPager->errCode) ) return pPager->errCode;
- pPager->iDataVersion++;
assert( pPager->eState==PAGER_WRITER_LOCKED
|| pPager->eState==PAGER_WRITER_FINISHED
|| (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
);
@@ -6688,10 +6637,11 @@
pPager->eState = PAGER_READER;
return SQLITE_OK;
}
PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
+ pPager->iDataVersion++;
rc = pager_end_transaction(pPager, pPager->setMaster, 1);
return pager_error(pPager, rc);
}
/*
@@ -7031,17 +6981,13 @@
** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when
** used to report the filename to the user, for compatibility with legacy
** behavior. But when the Btree needs to know the filename for matching to
** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
** participate in shared-cache.
-**
-** The return value to this routine is always safe to use with
-** sqlite3_uri_parameter() and sqlite3_filename_database() and friends.
*/
-const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){
- static const char zFake[] = { 0x00, 0x01, 0x00, 0x00, 0x00 };
- return (nullIfMemDb && pPager->memDb) ? &zFake[3] : pPager->zFilename;
+const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
+ return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
}
/*
** Return the VFS structure for the pager.
*/
@@ -7691,12 +7637,10 @@
if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
}
}
return rc;
}
-
-
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** If this is a WAL database, obtain a snapshot handle for the snapshot
** currently open. Otherwise, return an error.
Index: src/pager.h
==================================================================
--- src/pager.h
+++ src/pager.h
@@ -201,11 +201,11 @@
u32 sqlite3PagerDataVersion(Pager*);
#ifdef SQLITE_DEBUG
int sqlite3PagerRefcount(Pager*);
#endif
int sqlite3PagerMemUsed(Pager*);
-const char *sqlite3PagerFilename(const Pager*, int);
+const char *sqlite3PagerFilename(Pager*, int);
sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*);
sqlite3_file *sqlite3PagerJrnlFile(Pager*);
const char *sqlite3PagerJournalname(Pager*);
void *sqlite3PagerTempSpace(Pager*);
Index: src/parse.y
==================================================================
--- src/parse.y
+++ src/parse.y
@@ -104,13 +104,12 @@
/*
** Disable lookaside memory allocation for objects that might be
** shared across database connections.
*/
static void disableLookaside(Parse *pParse){
- sqlite3 *db = pParse->db;
pParse->disableLookaside++;
- DisableLookaside;
+ pParse->db->lookaside.bDisable++;
}
} // end %include
// Input is a single SQL command
@@ -118,11 +117,11 @@
cmdlist ::= cmdlist ecmd.
cmdlist ::= ecmd.
ecmd ::= SEMI.
ecmd ::= cmdx SEMI.
%ifndef SQLITE_OMIT_EXPLAIN
-ecmd ::= explain cmdx SEMI. {NEVER-REDUCE}
+ecmd ::= explain cmdx.
explain ::= EXPLAIN. { pParse->explain = 1; }
explain ::= EXPLAIN QUERY PLAN. { pParse->explain = 2; }
%endif SQLITE_OMIT_EXPLAIN
cmdx ::= cmd. { sqlite3FinishCoding(pParse); }
@@ -210,21 +209,17 @@
CONFLICT DATABASE DEFERRED DESC DETACH DO
EACH END EXCLUSIVE EXPLAIN FAIL FOR
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
- NULLS FIRST LAST
%ifdef SQLITE_OMIT_COMPOUND_SELECT
EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
%ifndef SQLITE_OMIT_WINDOWFUNC
CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
EXCLUDE GROUPS OTHERS TIES
%endif SQLITE_OMIT_WINDOWFUNC
-%ifndef SQLITE_OMIT_GENERATED_COLUMNS
- GENERATED ALWAYS
-%endif
REINDEX RENAME CTIME_KW IF
.
%wildcard ANY.
// Define operator precedence early so that this is the first occurrence
@@ -304,32 +299,28 @@
%type scanpt {const char*}
scanpt(A) ::= . {
assert( yyLookahead!=YYNOCODE );
A = yyLookaheadToken.z;
}
-scantok(A) ::= . {
- assert( yyLookahead!=YYNOCODE );
- A = yyLookaheadToken;
-}
// "carglist" is a list of additional constraints that come after the
// column name and column type in a CREATE TABLE statement.
//
carglist ::= carglist ccons.
carglist ::= .
ccons ::= CONSTRAINT nm(X). {pParse->constraintName = X;}
-ccons ::= DEFAULT scantok(A) term(X).
- {sqlite3AddDefaultValue(pParse,X,A.z,&A.z[A.n]);}
+ccons ::= DEFAULT scanpt(A) term(X) scanpt(Z).
+ {sqlite3AddDefaultValue(pParse,X,A,Z);}
ccons ::= DEFAULT LP(A) expr(X) RP(Z).
{sqlite3AddDefaultValue(pParse,X,A.z+1,Z.z);}
-ccons ::= DEFAULT PLUS(A) scantok(Z) term(X).
- {sqlite3AddDefaultValue(pParse,X,A.z,&Z.z[Z.n]);}
-ccons ::= DEFAULT MINUS(A) scantok(Z) term(X). {
+ccons ::= DEFAULT PLUS(A) term(X) scanpt(Z).
+ {sqlite3AddDefaultValue(pParse,X,A.z,Z);}
+ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z). {
Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0);
- sqlite3AddDefaultValue(pParse,p,A.z,&Z.z[Z.n]);
+ sqlite3AddDefaultValue(pParse,p,A.z,Z);
}
-ccons ::= DEFAULT scantok id(X). {
+ccons ::= DEFAULT scanpt id(X). {
Expr *p = tokenExpr(pParse, TK_STRING, X);
if( p ){
sqlite3ExprIdToTrueFalse(p);
testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
}
@@ -348,14 +339,10 @@
ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X);}
ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R).
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);}
ccons ::= COLLATE ids(C). {sqlite3AddCollateType(pParse, &C);}
-ccons ::= GENERATED ALWAYS AS generated.
-ccons ::= AS generated.
-generated ::= LP expr(E) RP. {sqlite3AddGenerated(pParse,E,0);}
-generated ::= LP expr(E) RP ID(TYPE). {sqlite3AddGenerated(pParse,E,&TYPE);}
// The optional AUTOINCREMENT keyword
%type autoinc {int}
autoinc(X) ::= . {X = 0;}
autoinc(X) ::= AUTOINCR. {X = 1;}
@@ -465,11 +452,10 @@
** For a compound SELECT statement, make sure p->pPrior->pNext==p for
** all elements in the list. And make sure list length does not exceed
** SQLITE_LIMIT_COMPOUND_SELECT.
*/
static void parserDoubleLinkSelect(Parse *pParse, Select *p){
- assert( p!=0 );
if( p->pPrior ){
Select *pNext = 0, *pLoop;
int mxSelect, cnt = 0;
for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
pLoop->pNext = pNext;
@@ -788,30 +774,25 @@
%type sortlist {ExprList*}
%destructor sortlist {sqlite3ExprListDelete(pParse->db, $$);}
orderby_opt(A) ::= . {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
-sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z) nulls(X). {
+sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). {
A = sqlite3ExprListAppend(pParse,A,Y);
- sqlite3ExprListSetSortOrder(A,Z,X);
+ sqlite3ExprListSetSortOrder(A,Z);
}
-sortlist(A) ::= expr(Y) sortorder(Z) nulls(X). {
+sortlist(A) ::= expr(Y) sortorder(Z). {
A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/
- sqlite3ExprListSetSortOrder(A,Z,X);
+ sqlite3ExprListSetSortOrder(A,Z);
}
%type sortorder {int}
sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;}
-%type nulls {int}
-nulls(A) ::= NULLS FIRST. {A = SQLITE_SO_ASC;}
-nulls(A) ::= NULLS LAST. {A = SQLITE_SO_DESC;}
-nulls(A) ::= . {A = SQLITE_SO_UNDEFINED;}
-
%type groupby_opt {ExprList*}
%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
groupby_opt(A) ::= . {A = 0;}
groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;}
@@ -961,11 +942,11 @@
static Expr *tokenExpr(Parse *pParse, int op, Token t){
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
if( p ){
/* memset(p, 0, sizeof(Expr)); */
p->op = (u8)op;
- p->affExpr = 0;
+ p->affinity = 0;
p->flags = EP_Leaf;
p->iAgg = -1;
p->pLeft = p->pRight = 0;
p->x.pList = 0;
p->pAggInfo = 0;
@@ -1057,15 +1038,15 @@
expr(A) ::= id(X) LP STAR RP. {
A = sqlite3ExprFunction(pParse, 0, &X, 0);
}
%ifndef SQLITE_OMIT_WINDOWFUNC
-expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP filter_over(Z). {
+expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP over_clause(Z). {
A = sqlite3ExprFunction(pParse, Y, &X, D);
sqlite3WindowAttach(pParse, A, Z);
}
-expr(A) ::= id(X) LP STAR RP filter_over(Z). {
+expr(A) ::= id(X) LP STAR RP over_clause(Z). {
A = sqlite3ExprFunction(pParse, 0, &X, 0);
sqlite3WindowAttach(pParse, A, Z);
}
%endif
@@ -1076,19 +1057,16 @@
expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
ExprList *pList = sqlite3ExprListAppend(pParse, X, Y);
A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
if( A ){
A->x.pList = pList;
- if( ALWAYS(pList->nExpr) ){
- A->flags |= pList->a[0].pExpr->flags & EP_Propagate;
- }
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
-expr(A) ::= expr(A) AND expr(Y). {A=sqlite3ExprAnd(pParse,A,Y);}
+expr(A) ::= expr(A) AND(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) OR(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
{A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) EQ|NE(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
@@ -1189,12 +1167,41 @@
** expr1 NOT IN ()
**
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- sqlite3ExprUnmapAndDelete(pParse, A);
- A = sqlite3Expr(pParse->db, TK_INTEGER, N ? "1" : "0");
+ if( IN_RENAME_OBJECT==0 ){
+ sqlite3ExprDelete(pParse->db, A);
+ A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1);
+ }
+ }else if( Y->nExpr==1 ){
+ /* Expressions of the form:
+ **
+ ** expr1 IN (?1)
+ ** expr1 NOT IN (?2)
+ **
+ ** with exactly one value on the RHS can be simplified to something
+ ** like this:
+ **
+ ** expr1 == ?1
+ ** expr1 <> ?2
+ **
+ ** But, the RHS of the == or <> is marked with the EP_Generic flag
+ ** so that it may not contribute to the computation of comparison
+ ** affinity or the collating sequence to use for comparison. Otherwise,
+ ** the semantics would be subtly different from IN or NOT IN.
+ */
+ Expr *pRHS = Y->a[0].pExpr;
+ Y->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, Y);
+ /* pRHS cannot be NULL because a malloc error would have been detected
+ ** before now and control would have never reached this point */
+ if( ALWAYS(pRHS) ){
+ pRHS->flags &= ~EP_Collate;
+ pRHS->flags |= EP_Generic;
+ }
+ A = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A, pRHS);
}else{
A = sqlite3PExpr(pParse, TK_IN, A, 0);
if( A ){
A->x.pList = Y;
sqlite3ExprSetHeightAndFlags(pParse, A);
@@ -1496,17 +1503,17 @@
// The special RAISE expression that may occur in trigger programs
expr(A) ::= RAISE LP IGNORE RP. {
A = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
if( A ){
- A->affExpr = OE_Ignore;
+ A->affinity = OE_Ignore;
}
}
expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. {
A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
if( A ) {
- A->affExpr = (char)T;
+ A->affinity = (char)T;
}
}
%endif !SQLITE_OMIT_TRIGGER
%type raisetype {int}
@@ -1646,18 +1653,12 @@
%destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);}
%type part_opt {ExprList*}
%destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);}
-%type filter_clause {Expr*}
-%destructor filter_clause {sqlite3ExprDelete(pParse->db, $$);}
-
-%type over_clause {Window*}
-%destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}
-
-%type filter_over {Window*}
-%destructor filter_over {sqlite3WindowDelete(pParse->db, $$);}
+%type filter_opt {Expr*}
+%destructor filter_opt {sqlite3ExprDelete(pParse->db, $$);}
%type range_or_rows {int}
%type frame_bound {struct FrameBound}
%destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
@@ -1719,52 +1720,42 @@
%type window_clause {Window*}
%destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);}
window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; }
-filter_over(A) ::= filter_clause(F) over_clause(O). {
- O->pFilter = F;
- A = O;
-}
-filter_over(A) ::= over_clause(O). {
- A = O;
-}
-filter_over(A) ::= filter_clause(F). {
- A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( A ){
- A->eFrmType = TK_FILTER;
- A->pFilter = F;
- }else{
- sqlite3ExprDelete(pParse->db, F);
- }
-}
-
-over_clause(A) ::= OVER LP window(Z) RP. {
- A = Z;
- assert( A!=0 );
-}
-over_clause(A) ::= OVER nm(Z). {
- A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( A ){
- A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
- }
-}
-
-filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; }
+%type over_clause {Window*}
+%destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}
+over_clause(A) ::= filter_opt(W) OVER LP window(Z) RP. {
+ A = Z;
+ assert( A!=0 );
+ A->pFilter = W;
+}
+over_clause(A) ::= filter_opt(W) OVER nm(Z). {
+ A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( A ){
+ A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
+ A->pFilter = W;
+ }else{
+ sqlite3ExprDelete(pParse->db, W);
+ }
+}
+
+filter_opt(A) ::= . { A = 0; }
+filter_opt(A) ::= FILTER LP WHERE expr(X) RP. { A = X; }
%endif /* SQLITE_OMIT_WINDOWFUNC */
/*
** The code generator needs some extra TK_ token values for tokens that
** are synthesized and do not actually appear in the grammar:
*/
%token
- COLUMN /* Reference to a table column */
- AGG_FUNCTION /* An aggregate function */
- AGG_COLUMN /* An aggregated column */
TRUEFALSE /* True or false keyword */
ISNOT /* Combination of IS and NOT */
FUNCTION /* A function invocation */
+ COLUMN /* Reference to a table column */
+ AGG_FUNCTION /* An aggregate function */
+ AGG_COLUMN /* An aggregated column */
UMINUS /* Unary minus */
UPLUS /* Unary plus */
TRUTH /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */
REGISTER /* Reference to a VDBE register */
VECTOR /* Vector */
Index: src/pcache.c
==================================================================
--- src/pcache.c
+++ src/pcache.c
@@ -241,14 +241,13 @@
if( p->szCache>=0 ){
/* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
** suggested cache size is set to N. */
return p->szCache;
}else{
- /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
- ** number of cache pages is adjusted to be a number of pages that would
- ** use approximately abs(N*1024) bytes of memory based on the current
- ** page size. */
+ /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
+ ** the number of cache pages is adjusted to use approximately abs(N*1024)
+ ** bytes of memory. */
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
}
}
/*************************************************** General Interfaces ******
@@ -260,11 +259,10 @@
if( sqlite3GlobalConfig.pcache2.xInit==0 ){
/* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
** built-in default page cache is used instead of the application defined
** page cache. */
sqlite3PCacheSetDefault();
- assert( sqlite3GlobalConfig.pcache2.xInit!=0 );
}
return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
}
void sqlite3PcacheShutdown(void){
if( sqlite3GlobalConfig.pcache2.xShutdown ){
Index: src/pcache1.c
==================================================================
--- src/pcache1.c
+++ src/pcache1.c
@@ -422,11 +422,10 @@
PgHdr1 *p = 0;
void *pPg;
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){
- assert( pCache->pFree!=0 );
p = pCache->pFree;
pCache->pFree = p->pNext;
p->pNext = 0;
}else{
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
@@ -446,19 +445,17 @@
sqlite3_free(p);
pPg = 0;
}
#else
pPg = pcache1Alloc(pCache->szAlloc);
+ p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
if( benignMalloc ){ sqlite3EndBenignMalloc(); }
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
pcache1EnterMutex(pCache->pGroup);
#endif
if( pPg==0 ) return 0;
-#ifndef SQLITE_PCACHE_SEPARATE_HEADER
- p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
-#endif
p->page.pBuf = pPg;
p->page.pExtra = &p[1];
p->isBulkLocal = 0;
p->isAnchor = 0;
}
@@ -779,20 +776,20 @@
pGroup = (PGroup*)&pCache[1];
pGroup->mxPinned = 10;
}else{
pGroup = &pcache1.grp;
}
- pcache1EnterMutex(pGroup);
if( pGroup->lru.isAnchor==0 ){
pGroup->lru.isAnchor = 1;
pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
}
pCache->pGroup = pGroup;
pCache->szPage = szPage;
pCache->szExtra = szExtra;
pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
pCache->bPurgeable = (bPurgeable ? 1 : 0);
+ pcache1EnterMutex(pGroup);
pcache1ResizeHash(pCache);
if( bPurgeable ){
pCache->nMin = 10;
pGroup->nMinPage += pCache->nMin;
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
Index: src/pragma.c
==================================================================
--- src/pragma.c
+++ src/pragma.c
@@ -292,59 +292,10 @@
lwr = mid + 1;
}
}
return lwr>upr ? 0 : &aPragmaName[mid];
}
-
-/*
-** Create zero or more entries in the output for the SQL functions
-** defined by FuncDef p.
-*/
-static void pragmaFunclistLine(
- Vdbe *v, /* The prepared statement being created */
- FuncDef *p, /* A particular function definition */
- int isBuiltin, /* True if this is a built-in function */
- int showInternFuncs /* True if showing internal functions */
-){
- for(; p; p=p->pNext){
- const char *zType;
- static const u32 mask =
- SQLITE_DETERMINISTIC |
- SQLITE_DIRECTONLY |
- SQLITE_SUBTYPE |
- SQLITE_INNOCUOUS |
- SQLITE_FUNC_INTERNAL
- ;
- static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };
-
- assert( SQLITE_FUNC_ENCMASK==0x3 );
- assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 );
- assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 );
- assert( strcmp(azEnc[SQLITE_UTF16BE],"utf16be")==0 );
-
- if( p->xSFunc==0 ) continue;
- if( (p->funcFlags & SQLITE_FUNC_INTERNAL)!=0
- && showInternFuncs==0
- ){
- continue;
- }
- if( p->xValue!=0 ){
- zType = "w";
- }else if( p->xFinalize!=0 ){
- zType = "a";
- }else{
- zType = "s";
- }
- sqlite3VdbeMultiLoad(v, 1, "sissii",
- p->zName, isBuiltin,
- zType, azEnc[p->funcFlags&SQLITE_FUNC_ENCMASK],
- p->nArg,
- (p->funcFlags & mask) ^ SQLITE_INNOCUOUS
- );
- }
-}
-
/*
** Helper subroutine for PRAGMA integrity_check:
**
** Generate code to output a single-column result row with a value of the
@@ -691,15 +642,10 @@
if( !zMode ){
/* If the "=MODE" part does not match any known journal mode,
** then do a query */
eMode = PAGER_JOURNALMODE_QUERY;
}
- if( eMode==PAGER_JOURNALMODE_OFF && (db->flags & SQLITE_Defensive)!=0 ){
- /* Do not allow journal-mode "OFF" in defensive since the database
- ** can become corrupted using ordinary SQL when the journal is off */
- eMode = PAGER_JOURNALMODE_QUERY;
- }
}
if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
/* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
iDb = 0;
pId2->n = 1;
@@ -1147,38 +1093,29 @@
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
pParse->nMem = 7;
sqlite3CodeVerifySchema(pParse, iTabDb);
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){
- int isHidden = 0;
- if( pCol->colFlags & COLFLAG_NOINSERT ){
- if( pPragma->iArg==0 ){
- nHidden++;
- continue;
- }
- if( pCol->colFlags & COLFLAG_VIRTUAL ){
- isHidden = 2; /* GENERATED ALWAYS AS ... VIRTUAL */
- }else if( pCol->colFlags & COLFLAG_STORED ){
- isHidden = 3; /* GENERATED ALWAYS AS ... STORED */
- }else{ assert( pCol->colFlags & COLFLAG_HIDDEN );
- isHidden = 1; /* HIDDEN */
- }
+ int isHidden = IsHiddenColumn(pCol);
+ if( isHidden && pPragma->iArg==0 ){
+ nHidden++;
+ continue;
}
if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
k = 0;
}else if( pPk==0 ){
k = 1;
}else{
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
- assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN || isHidden>=2 );
+ assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
i-nHidden,
pCol->zName,
sqlite3ColumnType(pCol,""),
pCol->notNull ? 1 : 0,
- pCol->pDflt && isHidden<2 ? pCol->pDflt->u.zToken : 0,
+ pCol->pDflt ? pCol->pDflt->u.zToken : 0,
k,
isHidden);
}
}
}
@@ -1213,19 +1150,10 @@
case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
Table *pTab;
pIdx = sqlite3FindIndex(db, zRight, zDb);
- if( pIdx==0 ){
- /* If there is no index named zRight, check to see if there is a
- ** WITHOUT ROWID table named zRight, and if there is, show the
- ** structure of the PRIMARY KEY index for that table. */
- pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
- if( pTab && !HasRowid(pTab) ){
- pIdx = sqlite3PrimaryKeyIndex(pTab);
- }
- }
if( pIdx ){
int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
int i;
int mx;
if( pPragma->iArg ){
@@ -1301,25 +1229,25 @@
sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
}
}
break;
-#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
+#ifdef SQLITE_INTROSPECTION_PRAGMAS
case PragTyp_FUNCTION_LIST: {
int i;
HashElem *j;
FuncDef *p;
- int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0;
- pParse->nMem = 6;
+ pParse->nMem = 2;
for(i=0; iu.pHash ){
- pragmaFunclistLine(v, p, 1, showInternFunc);
+ if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
+ sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
}
}
for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
p = (FuncDef*)sqliteHashData(j);
- pragmaFunclistLine(v, p, 0, showInternFunc);
+ sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0);
}
}
break;
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -1491,21 +1419,19 @@
}
break;
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
-#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/
case PragTyp_CASE_SENSITIVE_LIKE: {
if( zRight ){
sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
}
}
break;
-#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
#endif
@@ -1633,23 +1559,21 @@
assert( sqlite3NoTempsInRange(pParse,1,7+j) );
sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
if( !isQuick ){
/* Sanity check on record header decoding */
- sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3);
+ sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
}
/* Verify that all NOT NULL columns really are NOT NULL */
for(j=0; jnCol; j++){
char *zErr;
int jmp2;
if( j==pTab->iPKey ) continue;
if( pTab->aCol[j].notNull==0 ) continue;
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
- if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){
- sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
- }
+ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pTab->aCol[j].zName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
integrityCheckResultRow(v);
@@ -1822,21 +1746,14 @@
/* Only change the value of sqlite.enc if the database handle is not
** initialized. If the main database exists, the new sqlite.enc value
** will be overwritten when the schema is next loaded. If it does not
** already exists, it will be created to use the new encoding value.
*/
- int canChangeEnc = 1; /* True if allowed to change the encoding */
- int i; /* For looping over all attached databases */
- for(i=0; inDb; i++){
- if( db->aDb[i].pBt!=0
- && DbHasProperty(db,i,DB_SchemaLoaded)
- && !DbHasProperty(db,i,DB_Empty)
- ){
- canChangeEnc = 0;
- }
- }
- if( canChangeEnc ){
+ if(
+ !(DbHasProperty(db, 0, DB_SchemaLoaded)) ||
+ DbHasProperty(db, 0, DB_Empty)
+ ){
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
SCHEMA_ENC(db) = ENC(db) =
pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
break;
@@ -2145,31 +2062,10 @@
}
returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
break;
}
- /*
- ** PRAGMA hard_heap_limit
- ** PRAGMA hard_heap_limit = N
- **
- ** Invoke sqlite3_hard_heap_limit64() to query or set the hard heap
- ** limit. The hard heap limit can be activated or lowered by this
- ** pragma, but not raised or deactivated. Only the
- ** sqlite3_hard_heap_limit64() C-language API can raise or deactivate
- ** the hard heap limit. This allows an application to set a heap limit
- ** constraint that cannot be relaxed by an untrusted SQL script.
- */
- case PragTyp_HARD_HEAP_LIMIT: {
- sqlite3_int64 N;
- if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
- sqlite3_int64 iPrior = sqlite3_hard_heap_limit64(-1);
- if( N>0 && (iPrior==0 || iPrior>N) ) sqlite3_hard_heap_limit64(N);
- }
- returnSingleInt(v, sqlite3_hard_heap_limit64(-1));
- break;
- }
-
/*
** PRAGMA threads
** PRAGMA threads = N
**
** Configure the maximum number of worker threads. Return the new
@@ -2225,34 +2121,32 @@
** textkey 4
** textrekey 5
*/
case PragTyp_KEY: {
if( zRight ){
- char zBuf[40];
- const char *zKey = zRight;
- int n;
- if( pPragma->iArg==2 || pPragma->iArg==3 ){
- u8 iByte;
- int i;
- for(i=0, iByte=0; iiArg<4 ? sqlite3Strlen30(zRight) : -1;
+ if( (pPragma->iArg & 1)==0 ){
+ sqlite3_key_v2(db, zDb, zRight, n);
}else{
- n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
+ sqlite3_rekey_v2(db, zDb, zRight, n);
+ }
+ }
+ break;
+ }
+ case PragTyp_HEXKEY: {
+ if( zRight ){
+ u8 iByte;
+ int i;
+ char zKey[40];
+ for(i=0, iByte=0; iiArg & 1)==0 ){
- rc = sqlite3_key_v2(db, zDb, zKey, n);
+ sqlite3_key_v2(db, zDb, zKey, i/2);
}else{
- rc = sqlite3_rekey_v2(db, zDb, zKey, n);
- }
- if( rc==SQLITE_OK && n!=0 ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC);
- returnSingleText(v, "ok");
+ sqlite3_rekey_v2(db, zDb, zKey, i/2);
}
}
break;
}
#endif
Index: src/pragma.h
==================================================================
--- src/pragma.h
+++ src/pragma.h
@@ -19,36 +19,36 @@
#define PragTyp_DEFAULT_CACHE_SIZE 11
#define PragTyp_ENCODING 12
#define PragTyp_FOREIGN_KEY_CHECK 13
#define PragTyp_FOREIGN_KEY_LIST 14
#define PragTyp_FUNCTION_LIST 15
-#define PragTyp_HARD_HEAP_LIMIT 16
-#define PragTyp_INCREMENTAL_VACUUM 17
-#define PragTyp_INDEX_INFO 18
-#define PragTyp_INDEX_LIST 19
-#define PragTyp_INTEGRITY_CHECK 20
-#define PragTyp_JOURNAL_MODE 21
-#define PragTyp_JOURNAL_SIZE_LIMIT 22
-#define PragTyp_LOCK_PROXY_FILE 23
-#define PragTyp_LOCKING_MODE 24
-#define PragTyp_PAGE_COUNT 25
-#define PragTyp_MMAP_SIZE 26
-#define PragTyp_MODULE_LIST 27
-#define PragTyp_OPTIMIZE 28
-#define PragTyp_PAGE_SIZE 29
-#define PragTyp_PRAGMA_LIST 30
-#define PragTyp_SECURE_DELETE 31
-#define PragTyp_SHRINK_MEMORY 32
-#define PragTyp_SOFT_HEAP_LIMIT 33
-#define PragTyp_SYNCHRONOUS 34
-#define PragTyp_TABLE_INFO 35
-#define PragTyp_TEMP_STORE 36
-#define PragTyp_TEMP_STORE_DIRECTORY 37
-#define PragTyp_THREADS 38
-#define PragTyp_WAL_AUTOCHECKPOINT 39
-#define PragTyp_WAL_CHECKPOINT 40
-#define PragTyp_ACTIVATE_EXTENSIONS 41
+#define PragTyp_INCREMENTAL_VACUUM 16
+#define PragTyp_INDEX_INFO 17
+#define PragTyp_INDEX_LIST 18
+#define PragTyp_INTEGRITY_CHECK 19
+#define PragTyp_JOURNAL_MODE 20
+#define PragTyp_JOURNAL_SIZE_LIMIT 21
+#define PragTyp_LOCK_PROXY_FILE 22
+#define PragTyp_LOCKING_MODE 23
+#define PragTyp_PAGE_COUNT 24
+#define PragTyp_MMAP_SIZE 25
+#define PragTyp_MODULE_LIST 26
+#define PragTyp_OPTIMIZE 27
+#define PragTyp_PAGE_SIZE 28
+#define PragTyp_PRAGMA_LIST 29
+#define PragTyp_SECURE_DELETE 30
+#define PragTyp_SHRINK_MEMORY 31
+#define PragTyp_SOFT_HEAP_LIMIT 32
+#define PragTyp_SYNCHRONOUS 33
+#define PragTyp_TABLE_INFO 34
+#define PragTyp_TEMP_STORE 35
+#define PragTyp_TEMP_STORE_DIRECTORY 36
+#define PragTyp_THREADS 37
+#define PragTyp_WAL_AUTOCHECKPOINT 38
+#define PragTyp_WAL_CHECKPOINT 39
+#define PragTyp_ACTIVATE_EXTENSIONS 40
+#define PragTyp_HEXKEY 41
#define PragTyp_KEY 42
#define PragTyp_LOCK_STATUS 43
#define PragTyp_STATS 44
/* Property flags associated with various pragma. */
@@ -86,43 +86,39 @@
/* 16 */ "cid",
/* 17 */ "name",
/* 18 */ "desc",
/* 19 */ "coll",
/* 20 */ "key",
- /* 21 */ "name", /* Used by: function_list */
- /* 22 */ "builtin",
- /* 23 */ "type",
- /* 24 */ "enc",
- /* 25 */ "narg",
- /* 26 */ "flags",
- /* 27 */ "tbl", /* Used by: stats */
- /* 28 */ "idx",
- /* 29 */ "wdth",
- /* 30 */ "hght",
- /* 31 */ "flgs",
- /* 32 */ "seq", /* Used by: index_list */
- /* 33 */ "name",
- /* 34 */ "unique",
- /* 35 */ "origin",
- /* 36 */ "partial",
- /* 37 */ "table", /* Used by: foreign_key_check */
- /* 38 */ "rowid",
- /* 39 */ "parent",
- /* 40 */ "fkid",
+ /* 21 */ "tbl", /* Used by: stats */
+ /* 22 */ "idx",
+ /* 23 */ "wdth",
+ /* 24 */ "hght",
+ /* 25 */ "flgs",
+ /* 26 */ "seq", /* Used by: index_list */
+ /* 27 */ "name",
+ /* 28 */ "unique",
+ /* 29 */ "origin",
+ /* 30 */ "partial",
+ /* 31 */ "table", /* Used by: foreign_key_check */
+ /* 32 */ "rowid",
+ /* 33 */ "parent",
+ /* 34 */ "fkid",
/* index_info reuses 15 */
- /* 41 */ "seq", /* Used by: database_list */
- /* 42 */ "name",
- /* 43 */ "file",
- /* 44 */ "busy", /* Used by: wal_checkpoint */
- /* 45 */ "log",
- /* 46 */ "checkpointed",
- /* collation_list reuses 32 */
- /* 47 */ "database", /* Used by: lock_status */
- /* 48 */ "status",
- /* 49 */ "cache_size", /* Used by: default_cache_size */
+ /* 35 */ "seq", /* Used by: database_list */
+ /* 36 */ "name",
+ /* 37 */ "file",
+ /* 38 */ "busy", /* Used by: wal_checkpoint */
+ /* 39 */ "log",
+ /* 40 */ "checkpointed",
+ /* 41 */ "name", /* Used by: function_list */
+ /* 42 */ "builtin",
+ /* collation_list reuses 26 */
+ /* 43 */ "database", /* Used by: lock_status */
+ /* 44 */ "status",
+ /* 45 */ "cache_size", /* Used by: default_cache_size */
/* module_list pragma_list reuses 9 */
- /* 50 */ "timeout", /* Used by: busy_timeout */
+ /* 46 */ "timeout", /* Used by: busy_timeout */
};
/* Definitions of all built-in pragmas */
typedef struct PragmaName {
const char *const zName; /* Name of pragma */
@@ -164,11 +160,11 @@
#endif
#endif
{/* zName: */ "busy_timeout",
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 50, 1,
+ /* ColNames: */ 46, 1,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "cache_size",
/* ePragTyp: */ PragTyp_CACHE_SIZE,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
@@ -180,17 +176,15 @@
/* ePragTyp: */ PragTyp_CACHE_SPILL,
/* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
-#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
{/* zName: */ "case_sensitive_like",
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
/* ePragFlg: */ PragFlg_NoColumns,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
-#endif
{/* zName: */ "cell_size_check",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_CellSizeCk },
@@ -203,11 +197,11 @@
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{/* zName: */ "collation_list",
/* ePragTyp: */ PragTyp_COLLATION_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 32, 2,
+ /* ColNames: */ 26, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
{/* zName: */ "compile_options",
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
@@ -238,18 +232,18 @@
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{/* zName: */ "database_list",
/* ePragTyp: */ PragTyp_DATABASE_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
- /* ColNames: */ 41, 3,
+ /* ColNames: */ 35, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
{/* zName: */ "default_cache_size",
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
- /* ColNames: */ 49, 1,
+ /* ColNames: */ 45, 1,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
{/* zName: */ "defer_foreign_keys",
@@ -275,11 +269,11 @@
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
{/* zName: */ "foreign_key_check",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
- /* ColNames: */ 37, 4,
+ /* ColNames: */ 31, 4,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
{/* zName: */ "foreign_key_list",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
@@ -314,31 +308,26 @@
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_FullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
-#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
+#if defined(SQLITE_INTROSPECTION_PRAGMAS)
{/* zName: */ "function_list",
/* ePragTyp: */ PragTyp_FUNCTION_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 21, 6,
+ /* ColNames: */ 41, 2,
/* iArg: */ 0 },
#endif
#endif
- {/* zName: */ "hard_heap_limit",
- /* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT,
- /* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "hexkey",
- /* ePragTyp: */ PragTyp_KEY,
+ /* ePragTyp: */ PragTyp_HEXKEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 2 },
{/* zName: */ "hexrekey",
- /* ePragTyp: */ PragTyp_KEY,
+ /* ePragTyp: */ PragTyp_HEXKEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 3 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -364,11 +353,11 @@
/* ColNames: */ 15, 3,
/* iArg: */ 0 },
{/* zName: */ "index_list",
/* ePragTyp: */ PragTyp_INDEX_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 32, 5,
+ /* ColNames: */ 26, 5,
/* iArg: */ 0 },
{/* zName: */ "index_xinfo",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 15, 6,
@@ -404,10 +393,15 @@
{/* zName: */ "legacy_alter_table",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_LegacyAlter },
+ {/* zName: */ "legacy_file_format",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_LegacyFileFmt },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
{/* zName: */ "lock_proxy_file",
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
/* ePragFlg: */ PragFlg_NoColumns1,
@@ -416,11 +410,11 @@
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
{/* zName: */ "lock_status",
/* ePragTyp: */ PragTyp_LOCK_STATUS,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 47, 2,
+ /* ColNames: */ 43, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "locking_mode",
/* ePragTyp: */ PragTyp_LOCKING_MODE,
@@ -438,11 +432,11 @@
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
-#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
+#if defined(SQLITE_INTROSPECTION_PRAGMAS)
{/* zName: */ "module_list",
/* ePragTyp: */ PragTyp_MODULE_LIST,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 9, 1,
/* iArg: */ 0 },
@@ -473,11 +467,11 @@
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_ParserTrace },
#endif
#endif
-#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
+#if defined(SQLITE_INTROSPECTION_PRAGMAS)
{/* zName: */ "pragma_list",
/* ePragTyp: */ PragTyp_PRAGMA_LIST,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 9, 1,
/* iArg: */ 0 },
@@ -564,11 +558,11 @@
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
{/* zName: */ "stats",
/* ePragTyp: */ PragTyp_STATS,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 27, 5,
+ /* ColNames: */ 21, 5,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "synchronous",
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
@@ -615,17 +609,10 @@
{/* zName: */ "threads",
/* ePragTyp: */ PragTyp_THREADS,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
-#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "trusted_schema",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_TrustedSchema },
-#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{/* zName: */ "user_version",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
/* ColNames: */ 0, 0,
@@ -667,11 +654,11 @@
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
{/* zName: */ "wal_checkpoint",
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
/* ePragFlg: */ PragFlg_NeedSchema,
- /* ColNames: */ 44, 3,
+ /* ColNames: */ 38, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "writable_schema",
/* ePragTyp: */ PragTyp_FLAG,
@@ -678,6 +665,6 @@
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
-/* Number of pragmas: 66 on by default, 82 total. */
+/* Number of pragmas: 62 on by default, 81 total. */
Index: src/prepare.c
==================================================================
--- src/prepare.c
+++ src/prepare.c
@@ -54,22 +54,10 @@
for(p=pIndex->pTable->pIndex; p; p=p->pNext){
if( p->tnum==pIndex->tnum && p!=pIndex ) return 1;
}
return 0;
}
-
-/* forward declaration */
-static int sqlite3Prepare(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
- Vdbe *pReprepare, /* VM being reprepared */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-);
-
/*
** This is the callback routine for the code that initializes the
** database. See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
@@ -116,21 +104,20 @@
assert( db->init.busy );
db->init.iDb = iDb;
db->init.newTnum = sqlite3Atoi(argv[3]);
db->init.orphanTrigger = 0;
db->init.azInit = argv;
- pStmt = 0;
- TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0);
+ TESTONLY(rcp = ) sqlite3_prepare(db, argv[4], -1, &pStmt, 0);
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
db->init.iDb = saved_iDb;
/* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
if( SQLITE_OK!=rc ){
if( db->init.orphanTrigger ){
assert( iDb==1 );
}else{
- if( rc > pData->rc ) pData->rc = rc;
+ pData->rc = rc;
if( rc==SQLITE_NOMEM ){
sqlite3OomFault(db);
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
corruptSchema(pData, argv[1], sqlite3_errmsg(db));
}
@@ -538,11 +525,10 @@
sqlite3DbFree(db, pParse->aLabel);
sqlite3ExprListDelete(db, pParse->pConstExpr);
if( db ){
assert( db->lookaside.bDisable >= pParse->disableLookaside );
db->lookaside.bDisable -= pParse->disableLookaside;
- db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
}
pParse->disableLookaside = 0;
}
/*
@@ -572,11 +558,11 @@
/* For a long-term use prepared statement avoid the use of
** lookaside memory.
*/
if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
sParse.disableLookaside++;
- DisableLookaside;
+ db->lookaside.bDisable++;
}
sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;
/* Check to verify that it is possible to get a read lock on all
** database schemas. The inability to get a read lock indicates that
@@ -599,22 +585,20 @@
**
** Note that setting READ_UNCOMMITTED overrides most lock detection,
** but it does *not* override schema lock detection, so this all still
** works even if READ_UNCOMMITTED is set.
*/
- if( !db->noSharedCache ){
- for(i=0; inDb; i++) {
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- assert( sqlite3BtreeHoldsMutex(pBt) );
- rc = sqlite3BtreeSchemaLocked(pBt);
- if( rc ){
- const char *zDb = db->aDb[i].zDbSName;
- sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
- testcase( db->flags & SQLITE_ReadUncommit );
- goto end_prepare;
- }
+ for(i=0; inDb; i++) {
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
+ assert( sqlite3BtreeHoldsMutex(pBt) );
+ rc = sqlite3BtreeSchemaLocked(pBt);
+ if( rc ){
+ const char *zDb = db->aDb[i].zDbSName;
+ sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
+ testcase( db->flags & SQLITE_ReadUncommit );
+ goto end_prepare;
}
}
}
sqlite3VtabUnlockList(db);
@@ -641,29 +625,50 @@
}else{
sqlite3RunParser(&sParse, zSql, &zErrMsg);
}
assert( 0==sParse.nQueryLoop );
- if( sParse.rc==SQLITE_DONE ){
- sParse.rc = SQLITE_OK;
- }
+ if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
if( sParse.checkSchema ){
schemaIsValid(&sParse);
}
+ if( db->mallocFailed ){
+ sParse.rc = SQLITE_NOMEM_BKPT;
+ }
if( pzTail ){
*pzTail = sParse.zTail;
}
+ rc = sParse.rc;
+
+#ifndef SQLITE_OMIT_EXPLAIN
+ if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
+ static const char * const azColName[] = {
+ "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
+ "id", "parent", "notused", "detail"
+ };
+ int iFirst, mx;
+ if( sParse.explain==2 ){
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
+ iFirst = 8;
+ mx = 12;
+ }else{
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
+ iFirst = 0;
+ mx = 8;
+ }
+ for(i=iFirst; iinit.busy==0 ){
sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
}
- if( db->mallocFailed ){
- sParse.rc = SQLITE_NOMEM_BKPT;
- }
- rc = sParse.rc;
- if( rc!=SQLITE_OK ){
- if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe);
+ if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
+ sqlite3VdbeFinalize(sParse.pVdbe);
assert(!(*ppStmt));
}else{
*ppStmt = (sqlite3_stmt*)sParse.pVdbe;
}
Index: src/printf.c
==================================================================
--- src/printf.c
+++ src/printf.c
@@ -97,16 +97,10 @@
{ 'T', 0, 0, etTOKEN, 0, 0 },
{ 'S', 0, 0, etSRCLIST, 0, 0 },
{ 'r', 10, 1, etORDINAL, 0, 0 },
};
-/* Floating point constants used for rounding */
-static const double arRound[] = {
- 5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05,
- 5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10,
-};
-
/*
** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
** conversions will work.
*/
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -521,22 +515,12 @@
}else{
prefix = flag_prefix;
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
- idx = precision & 0xfff;
- rounder = arRound[idx%10];
- while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; }
- if( xtype==etFLOAT ){
- double rx = (double)realvalue;
- sqlite3_uint64 u;
- int ex;
- memcpy(&u, &rx, sizeof(u));
- ex = -1023 + (int)((u>>52)&0x7ff);
- if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16;
- realvalue += rounder;
- }
+ for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
+ if( xtype==etFLOAT ) realvalue += rounder;
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
if( sqlite3IsNaN((double)realvalue) ){
bufpt = "NaN";
length = 3;
Index: src/resolve.c
==================================================================
--- src/resolve.c
+++ src/resolve.c
@@ -94,17 +94,10 @@
if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
pExpr->flags |= EP_MemToken;
}
- if( ExprHasProperty(pExpr, EP_WinFunc) ){
- if( pExpr->y.pWin!=0 ){
- pExpr->y.pWin->pOwner = pExpr;
- }else{
- assert( db->mallocFailed );
- }
- }
sqlite3DbFree(db, pDup);
}
ExprSetProperty(pExpr, EP_Alias);
}
@@ -130,20 +123,17 @@
** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
** Check to see if the zSpan given to this routine matches the zDb, zTab,
** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
** match anything.
*/
-int sqlite3MatchEName(
- const struct ExprList_item *pItem,
+int sqlite3MatchSpanName(
+ const char *zSpan,
const char *zCol,
const char *zTab,
const char *zDb
){
int n;
- const char *zSpan;
- if( NEVER(pItem->eEName!=ENAME_TAB) ) return 0;
- zSpan = pItem->zEName;
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
return 0;
}
zSpan += n+1;
@@ -156,27 +146,10 @@
return 0;
}
return 1;
}
-/*
-** Return TRUE if the double-quoted string mis-feature should be supported.
-*/
-static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
- if( db->init.busy ) return 1; /* Always support for legacy schemas */
- if( pTopNC->ncFlags & NC_IsDDL ){
- /* Currently parsing a DDL statement */
- if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){
- return 1;
- }
- return (db->flags & SQLITE_DqsDDL)!=0;
- }else{
- /* Currently parsing a DML statement */
- return (db->flags & SQLITE_DqsDML)!=0;
- }
-}
-
/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr
** expression node refer back to that source column. The following changes
** are made to pExpr:
@@ -268,11 +241,11 @@
assert( pTab->nCol>0 );
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
int hit = 0;
pEList = pItem->pSelect->pEList;
for(j=0; jnExpr; j++){
- if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
+ if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
cnt++;
cntTab = 2;
pMatch = pItem;
pExpr->iColumn = j;
hit = 1;
@@ -389,11 +362,11 @@
}else
#endif /* SQLITE_OMIT_UPSERT */
{
#ifndef SQLITE_OMIT_TRIGGER
if( iCol<0 ){
- pExpr->affExpr = SQLITE_AFF_INTEGER;
+ pExpr->affinity = SQLITE_AFF_INTEGER;
}else if( pExpr->iTable==0 ){
testcase( iCol==31 );
testcase( iCol==32 );
pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<ncFlags & (NC_IdxExpr|NC_GenCol))==0
+ && (pNC->ncFlags & NC_IdxExpr)==0
&& sqlite3IsRowid(zCol)
&& VisibleRowid(pMatch->pTab)
){
cnt = 1;
pExpr->iColumn = -1;
- pExpr->affExpr = SQLITE_AFF_INTEGER;
+ pExpr->affinity = SQLITE_AFF_INTEGER;
}
/*
** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
** might refer to an result-set alias. This happens, for example, when
@@ -449,26 +422,22 @@
&& zTab==0
){
pEList = pNC->uNC.pEList;
assert( pEList!=0 );
for(j=0; jnExpr; j++){
- char *zAs = pEList->a[j].zEName;
- if( pEList->a[j].eEName==ENAME_NAME
- && sqlite3_stricmp(zAs, zCol)==0
- ){
+ char *zAs = pEList->a[j].zName;
+ if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
- if( ExprHasProperty(pOrig, EP_Win)
- && ((pNC->ncFlags&NC_AllowWin)==0 || pNC!=pTopNC )
- ){
+ if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){
sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
return WRC_Abort;
}
if( sqlite3ExprVectorSize(pOrig)!=1 ){
sqlite3ErrorMsg(pParse, "row value misused");
@@ -505,13 +474,11 @@
** Because no reference was made to outer contexts, the pNC->nRef
** fields are not changed in any context.
*/
if( cnt==0 && zTab==0 ){
assert( pExpr->op==TK_ID );
- if( ExprHasProperty(pExpr,EP_DblQuoted)
- && areDoubleQuotedStringsEnabled(db, pTopNC)
- ){
+ if( ExprHasProperty(pExpr,EP_DblQuoted) ){
/* If a double-quoted identifier does not match any known column name,
** then treat it as a string.
**
** This hack was added in the early days of SQLite in a misguided attempt
** to be compatible with MySQL 3.x, which used double-quotes for strings.
@@ -556,39 +523,22 @@
pTopNC->nErr++;
}
/* If a column from a table in pSrcList is referenced, then record
** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
- ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is
- ** set if the 63rd or any subsequent column is used.
- **
- ** The colUsed mask is an optimization used to help determine if an
- ** index is a covering index. The correct answer is still obtained
- ** if the mask contains extra set bits. However, it is important to
- ** avoid setting bits beyond the maximum column number of the table.
- ** (See ticket [b92e5e8ec2cdbaa1]).
- **
- ** If a generated column is referenced, set bits for every column
- ** of the table.
+ ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the
+ ** column number is greater than the number of bits in the bitmask
+ ** then set the high-order bit of the bitmask.
*/
if( pExpr->iColumn>=0 && pMatch!=0 ){
int n = pExpr->iColumn;
- Table *pExTab = pExpr->y.pTab;
- assert( pExTab!=0 );
+ testcase( n==BMS-1 );
+ if( n>=BMS ){
+ n = BMS-1;
+ }
assert( pMatch->iCursor==pExpr->iTable );
- if( (pExTab->tabFlags & TF_HasGenerated)!=0
- && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
- ){
- testcase( pExTab->nCol==BMS-1 );
- testcase( pExTab->nCol==BMS );
- pMatch->colUsed = pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
- }else{
- testcase( n==BMS-1 );
- testcase( n==BMS );
- if( n>=BMS ) n = BMS-1;
- pMatch->colUsed |= ((Bitmask)1)<