|
@@ -1149,7 +1149,7 @@ extern "C" {
|
|
|
*/
|
|
*/
|
|
|
#define SQLITE_VERSION "3.23.0"
|
|
#define SQLITE_VERSION "3.23.0"
|
|
|
#define SQLITE_VERSION_NUMBER 3023000
|
|
#define SQLITE_VERSION_NUMBER 3023000
|
|
|
-#define SQLITE_SOURCE_ID "2018-02-18 17:50:03 2df6bbf1b8ca881c8a465d6624de66fde4c5975ccae6b2f2dda392b137f5alt1"
|
|
|
|
|
|
|
+#define SQLITE_SOURCE_ID "2018-02-26 15:27:31 a983fa857048c748112c2f805f13aadeae43b43b3d27fa55433a3699b51calt1"
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
@@ -3522,16 +3522,16 @@ SQLITE_API void sqlite3_free_table(char **result);
|
|
|
**
|
|
**
|
|
|
** These routines are work-alikes of the "printf()" family of functions
|
|
** These routines are work-alikes of the "printf()" family of functions
|
|
|
** from the standard C library.
|
|
** from the standard C library.
|
|
|
-** These routines understand most of the common K&R formatting options,
|
|
|
|
|
-** plus some additional non-standard formats, detailed below.
|
|
|
|
|
-** Note that some of the more obscure formatting options from recent
|
|
|
|
|
-** C-library standards are omitted from this implementation.
|
|
|
|
|
|
|
+** These routines understand most of the common formatting options from
|
|
|
|
|
+** the standard library printf()
|
|
|
|
|
+** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
|
|
|
|
|
+** See the [built-in printf()] documentation for details.
|
|
|
**
|
|
**
|
|
|
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
|
|
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
|
|
|
-** results into memory obtained from [sqlite3_malloc()].
|
|
|
|
|
|
|
+** results into memory obtained from [sqlite3_malloc64()].
|
|
|
** The strings returned by these two routines should be
|
|
** The strings returned by these two routines should be
|
|
|
** released by [sqlite3_free()]. ^Both routines return a
|
|
** released by [sqlite3_free()]. ^Both routines return a
|
|
|
-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
|
|
|
|
|
|
|
+** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
|
|
|
** memory to hold the resulting string.
|
|
** memory to hold the resulting string.
|
|
|
**
|
|
**
|
|
|
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
|
|
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
|
|
@@ -3555,71 +3555,7 @@ SQLITE_API void sqlite3_free_table(char **result);
|
|
|
**
|
|
**
|
|
|
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
|
|
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
|
|
|
**
|
|
**
|
|
|
-** These routines all implement some additional formatting
|
|
|
|
|
-** options that are useful for constructing SQL statements.
|
|
|
|
|
-** All of the usual printf() formatting options apply. In addition, there
|
|
|
|
|
-** is are "%q", "%Q", "%w" and "%z" options.
|
|
|
|
|
-**
|
|
|
|
|
-** ^(The %q option works like %s in that it substitutes a nul-terminated
|
|
|
|
|
-** string from the argument list. But %q also doubles every '\'' character.
|
|
|
|
|
-** %q is designed for use inside a string literal.)^ By doubling each '\''
|
|
|
|
|
-** character it escapes that character and allows it to be inserted into
|
|
|
|
|
-** the string.
|
|
|
|
|
-**
|
|
|
|
|
-** For example, assume the string variable zText contains text as follows:
|
|
|
|
|
-**
|
|
|
|
|
-** <blockquote><pre>
|
|
|
|
|
-** char *zText = "It's a happy day!";
|
|
|
|
|
-** </pre></blockquote>
|
|
|
|
|
-**
|
|
|
|
|
-** One can use this text in an SQL statement as follows:
|
|
|
|
|
-**
|
|
|
|
|
-** <blockquote><pre>
|
|
|
|
|
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
|
|
|
|
|
-** sqlite3_exec(db, zSQL, 0, 0, 0);
|
|
|
|
|
-** sqlite3_free(zSQL);
|
|
|
|
|
-** </pre></blockquote>
|
|
|
|
|
-**
|
|
|
|
|
-** Because the %q format string is used, the '\'' character in zText
|
|
|
|
|
-** is escaped and the SQL generated is as follows:
|
|
|
|
|
-**
|
|
|
|
|
-** <blockquote><pre>
|
|
|
|
|
-** INSERT INTO table1 VALUES('It''s a happy day!')
|
|
|
|
|
-** </pre></blockquote>
|
|
|
|
|
-**
|
|
|
|
|
-** This is correct. Had we used %s instead of %q, the generated SQL
|
|
|
|
|
-** would have looked like this:
|
|
|
|
|
-**
|
|
|
|
|
-** <blockquote><pre>
|
|
|
|
|
-** INSERT INTO table1 VALUES('It's a happy day!');
|
|
|
|
|
-** </pre></blockquote>
|
|
|
|
|
-**
|
|
|
|
|
-** This second example is an SQL syntax error. As a general rule you should
|
|
|
|
|
-** always use %q instead of %s when inserting text into a string literal.
|
|
|
|
|
-**
|
|
|
|
|
-** ^(The %Q option works like %q except it also adds single quotes around
|
|
|
|
|
-** the outside of the total string. Additionally, if the parameter in the
|
|
|
|
|
-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
|
|
|
|
|
-** single quotes).)^ So, for example, one could say:
|
|
|
|
|
-**
|
|
|
|
|
-** <blockquote><pre>
|
|
|
|
|
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
|
|
|
|
|
-** sqlite3_exec(db, zSQL, 0, 0, 0);
|
|
|
|
|
-** sqlite3_free(zSQL);
|
|
|
|
|
-** </pre></blockquote>
|
|
|
|
|
-**
|
|
|
|
|
-** The code above will render a correct SQL statement in the zSQL
|
|
|
|
|
-** variable even if the zText variable is a NULL pointer.
|
|
|
|
|
-**
|
|
|
|
|
-** ^(The "%w" formatting option is like "%q" except that it expects to
|
|
|
|
|
-** be contained within double-quotes instead of single quotes, and it
|
|
|
|
|
-** escapes the double-quote character instead of the single-quote
|
|
|
|
|
-** character.)^ The "%w" formatting option is intended for safely inserting
|
|
|
|
|
-** table and column names into a constructed SQL statement.
|
|
|
|
|
-**
|
|
|
|
|
-** ^(The "%z" formatting option works like "%s" but with the
|
|
|
|
|
-** addition that after the string has been read and copied into
|
|
|
|
|
-** the result, [sqlite3_free()] is called on the input string.)^
|
|
|
|
|
|
|
+** See also: [built-in printf()], [printf() SQL function]
|
|
|
*/
|
|
*/
|
|
|
SQLITE_API char *sqlite3_mprintf(const char*,...);
|
|
SQLITE_API char *sqlite3_mprintf(const char*,...);
|
|
|
SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
|
|
SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
|
|
@@ -19153,6 +19089,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
|
|
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
|
|
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
|
|
|
SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
|
|
SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
|
|
|
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
|
|
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
|
|
|
|
|
+SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull);
|
|
|
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
|
|
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
|
|
|
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
|
|
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
|
|
|
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
|
|
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
|
|
@@ -26102,6 +26039,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|
|
PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
|
|
PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
|
|
|
char buf[etBUFSIZE]; /* Conversion buffer */
|
|
char buf[etBUFSIZE]; /* Conversion buffer */
|
|
|
|
|
|
|
|
|
|
+ /* pAccum never starts out with an empty buffer that was obtained from
|
|
|
|
|
+ ** malloc(). This precondition is required by the mprintf("%z...")
|
|
|
|
|
+ ** optimization. */
|
|
|
|
|
+ assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
|
|
|
|
|
+
|
|
|
bufpt = 0;
|
|
bufpt = 0;
|
|
|
if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
|
|
if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
|
|
|
pArgList = va_arg(ap, PrintfArguments*);
|
|
pArgList = va_arg(ap, PrintfArguments*);
|
|
@@ -26520,9 +26462,38 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|
|
case etCHARX:
|
|
case etCHARX:
|
|
|
if( bArgList ){
|
|
if( bArgList ){
|
|
|
bufpt = getTextArg(pArgList);
|
|
bufpt = getTextArg(pArgList);
|
|
|
- c = bufpt ? bufpt[0] : 0;
|
|
|
|
|
|
|
+ length = 1;
|
|
|
|
|
+ if( bufpt ){
|
|
|
|
|
+ buf[0] = c = *(bufpt++);
|
|
|
|
|
+ if( (c&0xc0)==0xc0 ){
|
|
|
|
|
+ while( length<4 && (bufpt[0]&0xc0)==0x80 ){
|
|
|
|
|
+ buf[length++] = *(bufpt++);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }else{
|
|
|
|
|
+ buf[0] = 0;
|
|
|
|
|
+ }
|
|
|
}else{
|
|
}else{
|
|
|
- c = va_arg(ap,int);
|
|
|
|
|
|
|
+ unsigned int ch = va_arg(ap,unsigned int);
|
|
|
|
|
+ if( ch<0x00080 ){
|
|
|
|
|
+ buf[0] = ch & 0xff;
|
|
|
|
|
+ length = 1;
|
|
|
|
|
+ }else if( ch<0x00800 ){
|
|
|
|
|
+ buf[0] = 0xc0 + (u8)((ch>>6)&0x1f);
|
|
|
|
|
+ buf[1] = 0x80 + (u8)(ch & 0x3f);
|
|
|
|
|
+ length = 2;
|
|
|
|
|
+ }else if( ch<0x10000 ){
|
|
|
|
|
+ buf[0] = 0xe0 + (u8)((ch>>12)&0x0f);
|
|
|
|
|
+ buf[1] = 0x80 + (u8)((ch>>6) & 0x3f);
|
|
|
|
|
+ buf[2] = 0x80 + (u8)(ch & 0x3f);
|
|
|
|
|
+ length = 3;
|
|
|
|
|
+ }else{
|
|
|
|
|
+ buf[0] = 0xf0 + (u8)((ch>>18) & 0x07);
|
|
|
|
|
+ buf[1] = 0x80 + (u8)((ch>>12) & 0x3f);
|
|
|
|
|
+ buf[2] = 0x80 + (u8)((ch>>6) & 0x3f);
|
|
|
|
|
+ buf[3] = 0x80 + (u8)(ch & 0x3f);
|
|
|
|
|
+ length = 4;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
if( precision>1 ){
|
|
if( precision>1 ){
|
|
|
width -= precision-1;
|
|
width -= precision-1;
|
|
@@ -26530,12 +26501,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|
|
sqlite3AppendChar(pAccum, width-1, ' ');
|
|
sqlite3AppendChar(pAccum, width-1, ' ');
|
|
|
width = 0;
|
|
width = 0;
|
|
|
}
|
|
}
|
|
|
- sqlite3AppendChar(pAccum, precision-1, c);
|
|
|
|
|
|
|
+ while( precision-- > 1 ){
|
|
|
|
|
+ sqlite3StrAccumAppend(pAccum, buf, length);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- length = 1;
|
|
|
|
|
- buf[0] = c;
|
|
|
|
|
bufpt = buf;
|
|
bufpt = buf;
|
|
|
- break;
|
|
|
|
|
|
|
+ flag_altform2 = 1;
|
|
|
|
|
+ goto adjust_width_for_utf8;
|
|
|
case etSTRING:
|
|
case etSTRING:
|
|
|
case etDYNSTRING:
|
|
case etDYNSTRING:
|
|
|
if( bArgList ){
|
|
if( bArgList ){
|
|
@@ -26547,17 +26519,45 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|
|
if( bufpt==0 ){
|
|
if( bufpt==0 ){
|
|
|
bufpt = "";
|
|
bufpt = "";
|
|
|
}else if( xtype==etDYNSTRING ){
|
|
}else if( xtype==etDYNSTRING ){
|
|
|
|
|
+ if( pAccum->nChar==0 && pAccum->mxAlloc && width==0 && precision<0 ){
|
|
|
|
|
+ /* Special optimization for sqlite3_mprintf("%z..."):
|
|
|
|
|
+ ** Extend an existing memory allocation rather than creating
|
|
|
|
|
+ ** a new one. */
|
|
|
|
|
+ assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
|
|
|
|
|
+ pAccum->zText = bufpt;
|
|
|
|
|
+ pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt);
|
|
|
|
|
+ pAccum->nChar = 0x7fffffff & (int)strlen(bufpt);
|
|
|
|
|
+ pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED;
|
|
|
|
|
+ length = 0;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
zExtra = bufpt;
|
|
zExtra = bufpt;
|
|
|
}
|
|
}
|
|
|
if( precision>=0 ){
|
|
if( precision>=0 ){
|
|
|
- for(length=0; length<precision && bufpt[length]; length++){}
|
|
|
|
|
|
|
+ if( flag_altform2 ){
|
|
|
|
|
+ /* Set length to the number of bytes needed in order to display
|
|
|
|
|
+ ** precision characters */
|
|
|
|
|
+ unsigned char *z = (unsigned char*)bufpt;
|
|
|
|
|
+ while( precision-- > 0 && z[0] ){
|
|
|
|
|
+ SQLITE_SKIP_UTF8(z);
|
|
|
|
|
+ }
|
|
|
|
|
+ length = (int)(z - (unsigned char*)bufpt);
|
|
|
|
|
+ }else{
|
|
|
|
|
+ for(length=0; length<precision && bufpt[length]; length++){}
|
|
|
|
|
+ }
|
|
|
}else{
|
|
}else{
|
|
|
length = 0x7fffffff & (int)strlen(bufpt);
|
|
length = 0x7fffffff & (int)strlen(bufpt);
|
|
|
}
|
|
}
|
|
|
|
|
+ adjust_width_for_utf8:
|
|
|
|
|
+ if( flag_altform2 && width>0 ){
|
|
|
|
|
+ /* Adjust width to account for extra bytes in UTF-8 characters */
|
|
|
|
|
+ int ii = length - 1;
|
|
|
|
|
+ while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
|
|
|
|
|
+ }
|
|
|
break;
|
|
break;
|
|
|
- case etSQLESCAPE: /* Escape ' characters */
|
|
|
|
|
- case etSQLESCAPE2: /* Escape ' and enclose in '...' */
|
|
|
|
|
- case etSQLESCAPE3: { /* Escape " characters */
|
|
|
|
|
|
|
+ case etSQLESCAPE: /* %q: Escape ' characters */
|
|
|
|
|
+ case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */
|
|
|
|
|
+ case etSQLESCAPE3: { /* %w: Escape " characters */
|
|
|
int i, j, k, n, isnull;
|
|
int i, j, k, n, isnull;
|
|
|
int needQuote;
|
|
int needQuote;
|
|
|
char ch;
|
|
char ch;
|
|
@@ -26571,9 +26571,17 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|
|
}
|
|
}
|
|
|
isnull = escarg==0;
|
|
isnull = escarg==0;
|
|
|
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
|
|
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
|
|
|
|
|
+ /* For %q, %Q, and %w, the precision is the number of byte (or
|
|
|
|
|
+ ** characters if the ! flags is present) to use from the input.
|
|
|
|
|
+ ** Because of the extra quoting characters inserted, the number
|
|
|
|
|
+ ** of output characters may be larger than the precision.
|
|
|
|
|
+ */
|
|
|
k = precision;
|
|
k = precision;
|
|
|
for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
|
|
for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
|
|
|
if( ch==q ) n++;
|
|
if( ch==q ) n++;
|
|
|
|
|
+ if( flag_altform2 && (ch&0xc0)==0xc0 ){
|
|
|
|
|
+ while( (escarg[i+1]&0xc0)==0x80 ){ i++; }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
needQuote = !isnull && xtype==etSQLESCAPE2;
|
|
needQuote = !isnull && xtype==etSQLESCAPE2;
|
|
|
n += i + 3;
|
|
n += i + 3;
|
|
@@ -26596,10 +26604,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|
|
if( needQuote ) bufpt[j++] = q;
|
|
if( needQuote ) bufpt[j++] = q;
|
|
|
bufpt[j] = 0;
|
|
bufpt[j] = 0;
|
|
|
length = j;
|
|
length = j;
|
|
|
- /* The precision in %q and %Q means how many input characters to
|
|
|
|
|
- ** consume, not the length of the output...
|
|
|
|
|
- ** if( precision>=0 && precision<length ) length = precision; */
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ goto adjust_width_for_utf8;
|
|
|
}
|
|
}
|
|
|
case etTOKEN: {
|
|
case etTOKEN: {
|
|
|
Token *pToken;
|
|
Token *pToken;
|
|
@@ -26638,7 +26643,10 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|
|
/*
|
|
/*
|
|
|
** The text of the conversion is pointed to by "bufpt" and is
|
|
** The text of the conversion is pointed to by "bufpt" and is
|
|
|
** "length" characters long. The field width is "width". Do
|
|
** "length" characters long. The field width is "width". Do
|
|
|
- ** the output.
|
|
|
|
|
|
|
+ ** the output. Both length and width are in bytes, not characters,
|
|
|
|
|
+ ** at this point. If the "!" flag was present on string conversions
|
|
|
|
|
+ ** indicating that width and precision should be expressed in characters,
|
|
|
|
|
+ ** then the values have been translated prior to reaching this point.
|
|
|
*/
|
|
*/
|
|
|
width -= length;
|
|
width -= length;
|
|
|
if( width>0 ){
|
|
if( width>0 ){
|
|
@@ -31390,7 +31398,11 @@ static struct unix_syscall {
|
|
|
#endif
|
|
#endif
|
|
|
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
|
|
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
|
|
|
|
|
|
|
|
|
|
+#if defined(HAVE_FCHOWN)
|
|
|
{ "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
|
|
{ "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
|
|
|
|
|
+#else
|
|
|
|
|
+ { "geteuid", (sqlite3_syscall_ptr)0, 0 },
|
|
|
|
|
+#endif
|
|
|
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
|
|
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
|
|
|
|
|
|
|
|
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
|
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
|
@@ -35098,12 +35110,10 @@ static int unixShmSystemLock(
|
|
|
|
|
|
|
|
if( pShmNode->h>=0 ){
|
|
if( pShmNode->h>=0 ){
|
|
|
/* Initialize the locking parameters */
|
|
/* Initialize the locking parameters */
|
|
|
- memset(&f, 0, sizeof(f));
|
|
|
|
|
f.l_type = lockType;
|
|
f.l_type = lockType;
|
|
|
f.l_whence = SEEK_SET;
|
|
f.l_whence = SEEK_SET;
|
|
|
f.l_start = ofst;
|
|
f.l_start = ofst;
|
|
|
f.l_len = n;
|
|
f.l_len = n;
|
|
|
-
|
|
|
|
|
rc = osFcntl(pShmNode->h, F_SETLK, &f);
|
|
rc = osFcntl(pShmNode->h, F_SETLK, &f);
|
|
|
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
|
|
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
|
|
|
}
|
|
}
|
|
@@ -56357,7 +56367,11 @@ struct WalIterator {
|
|
|
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
|
|
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
|
|
|
** then an SQLite error code is returned and *ppPage is set to 0.
|
|
** then an SQLite error code is returned and *ppPage is set to 0.
|
|
|
*/
|
|
*/
|
|
|
-static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
|
|
|
|
|
|
|
+static SQLITE_NOINLINE int walIndexPageRealloc(
|
|
|
|
|
+ Wal *pWal, /* The WAL context */
|
|
|
|
|
+ int iPage, /* The page we seek */
|
|
|
|
|
+ volatile u32 **ppPage /* Write the page pointer here */
|
|
|
|
|
+){
|
|
|
int rc = SQLITE_OK;
|
|
int rc = SQLITE_OK;
|
|
|
|
|
|
|
|
/* Enlarge the pWal->apWiData[] array if required */
|
|
/* Enlarge the pWal->apWiData[] array if required */
|
|
@@ -56376,21 +56390,20 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Request a pointer to the required page from the VFS */
|
|
/* Request a pointer to the required page from the VFS */
|
|
|
- if( pWal->apWiData[iPage]==0 ){
|
|
|
|
|
- if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
|
|
|
|
|
- pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
|
|
|
|
|
- if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
|
|
|
|
|
- }else{
|
|
|
|
|
- rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
|
|
|
|
|
- pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
|
|
|
|
|
- );
|
|
|
|
|
- assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
|
|
|
|
|
- testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
|
|
|
|
|
- if( (rc&0xff)==SQLITE_READONLY ){
|
|
|
|
|
- pWal->readOnly |= WAL_SHM_RDONLY;
|
|
|
|
|
- if( rc==SQLITE_READONLY ){
|
|
|
|
|
- rc = SQLITE_OK;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ assert( pWal->apWiData[iPage]==0 );
|
|
|
|
|
+ if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
|
|
|
|
|
+ pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
|
|
|
|
|
+ if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
|
|
|
|
|
+ }else{
|
|
|
|
|
+ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
|
|
|
|
|
+ pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
|
|
|
|
|
+ );
|
|
|
|
|
+ assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
|
|
|
|
|
+ testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
|
|
|
|
|
+ if( (rc&0xff)==SQLITE_READONLY ){
|
|
|
|
|
+ pWal->readOnly |= WAL_SHM_RDONLY;
|
|
|
|
|
+ if( rc==SQLITE_READONLY ){
|
|
|
|
|
+ rc = SQLITE_OK;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -56399,6 +56412,16 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
|
|
|
assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
|
|
assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
|
|
|
return rc;
|
|
return rc;
|
|
|
}
|
|
}
|
|
|
|
|
+static int walIndexPage(
|
|
|
|
|
+ Wal *pWal, /* The WAL context */
|
|
|
|
|
+ int iPage, /* The page we seek */
|
|
|
|
|
+ volatile u32 **ppPage /* Write the page pointer here */
|
|
|
|
|
+){
|
|
|
|
|
+ if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){
|
|
|
|
|
+ return walIndexPageRealloc(pWal, iPage, ppPage);
|
|
|
|
|
+ }
|
|
|
|
|
+ return SQLITE_OK;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
** Return a pointer to the WalCkptInfo structure in the wal-index.
|
|
** Return a pointer to the WalCkptInfo structure in the wal-index.
|
|
@@ -58671,7 +58694,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
|
|
|
** table after the current read-transaction had started.
|
|
** table after the current read-transaction had started.
|
|
|
*/
|
|
*/
|
|
|
iMinHash = walFramePage(pWal->minFrame);
|
|
iMinHash = walFramePage(pWal->minFrame);
|
|
|
- for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){
|
|
|
|
|
|
|
+ for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
|
|
|
volatile ht_slot *aHash; /* Pointer to hash table */
|
|
volatile ht_slot *aHash; /* Pointer to hash table */
|
|
|
volatile u32 *aPgno; /* Pointer to array of page numbers */
|
|
volatile u32 *aPgno; /* Pointer to array of page numbers */
|
|
|
u32 iZero; /* Frame number corresponding to aPgno[0] */
|
|
u32 iZero; /* Frame number corresponding to aPgno[0] */
|
|
@@ -58694,6 +58717,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
|
|
|
return SQLITE_CORRUPT_BKPT;
|
|
return SQLITE_CORRUPT_BKPT;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ if( iRead ) break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
|
|
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
|
|
@@ -64993,11 +65017,19 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
|
|
** Using this cache reduces the number of calls to btreeParseCell().
|
|
** Using this cache reduces the number of calls to btreeParseCell().
|
|
|
*/
|
|
*/
|
|
|
#ifndef NDEBUG
|
|
#ifndef NDEBUG
|
|
|
|
|
+ static int cellInfoEqual(CellInfo *a, CellInfo *b){
|
|
|
|
|
+ if( a->nKey!=b->nKey ) return 0;
|
|
|
|
|
+ if( a->pPayload!=b->pPayload ) return 0;
|
|
|
|
|
+ if( a->nPayload!=b->nPayload ) return 0;
|
|
|
|
|
+ if( a->nLocal!=b->nLocal ) return 0;
|
|
|
|
|
+ if( a->nSize!=b->nSize ) return 0;
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
static void assertCellInfo(BtCursor *pCur){
|
|
static void assertCellInfo(BtCursor *pCur){
|
|
|
CellInfo info;
|
|
CellInfo info;
|
|
|
memset(&info, 0, sizeof(info));
|
|
memset(&info, 0, sizeof(info));
|
|
|
btreeParseCell(pCur->pPage, pCur->ix, &info);
|
|
btreeParseCell(pCur->pPage, pCur->ix, &info);
|
|
|
- assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
|
|
|
|
|
|
|
+ assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) );
|
|
|
}
|
|
}
|
|
|
#else
|
|
#else
|
|
|
#define assertCellInfo(x)
|
|
#define assertCellInfo(x)
|
|
@@ -71964,6 +71996,16 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+** Return 1 if pMem represents true, and return 0 if pMem represents false.
|
|
|
|
|
+** Return the value ifNull if pMem is NULL.
|
|
|
|
|
+*/
|
|
|
|
|
+SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
|
|
|
|
|
+ if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
|
|
|
|
|
+ if( pMem->flags & MEM_Null ) return ifNull;
|
|
|
|
|
+ return sqlite3VdbeRealValue(pMem)!=0.0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
** The MEM structure is already a MEM_Real. Try to also make it a
|
|
** The MEM structure is already a MEM_Real. Try to also make it a
|
|
|
** MEM_Int if we can.
|
|
** MEM_Int if we can.
|
|
@@ -82405,18 +82447,8 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
|
|
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
|
|
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
|
|
|
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
|
|
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
|
|
|
|
|
|
|
|
- pIn1 = &aMem[pOp->p1];
|
|
|
|
|
- if( pIn1->flags & MEM_Null ){
|
|
|
|
|
- v1 = 2;
|
|
|
|
|
- }else{
|
|
|
|
|
- v1 = sqlite3VdbeIntValue(pIn1)!=0;
|
|
|
|
|
- }
|
|
|
|
|
- pIn2 = &aMem[pOp->p2];
|
|
|
|
|
- if( pIn2->flags & MEM_Null ){
|
|
|
|
|
- v2 = 2;
|
|
|
|
|
- }else{
|
|
|
|
|
- v2 = sqlite3VdbeIntValue(pIn2)!=0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2);
|
|
|
|
|
+ v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2);
|
|
|
if( pOp->opcode==OP_And ){
|
|
if( pOp->opcode==OP_And ){
|
|
|
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
|
|
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
|
|
|
v1 = and_logic[v1*3+v2];
|
|
v1 = and_logic[v1*3+v2];
|
|
@@ -82447,7 +82479,7 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */
|
|
|
sqlite3VdbeMemSetNull(pOut);
|
|
sqlite3VdbeMemSetNull(pOut);
|
|
|
if( (pIn1->flags & MEM_Null)==0 ){
|
|
if( (pIn1->flags & MEM_Null)==0 ){
|
|
|
pOut->flags = MEM_Int;
|
|
pOut->flags = MEM_Int;
|
|
|
- pOut->u.i = !sqlite3VdbeIntValue(pIn1);
|
|
|
|
|
|
|
+ pOut->u.i = !sqlite3VdbeBooleanValue(pIn1, 0);
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -82514,30 +82546,25 @@ case OP_Once: { /* jump */
|
|
|
** is considered true if it is numeric and non-zero. If the value
|
|
** is considered true if it is numeric and non-zero. If the value
|
|
|
** in P1 is NULL then take the jump if and only if P3 is non-zero.
|
|
** in P1 is NULL then take the jump if and only if P3 is non-zero.
|
|
|
*/
|
|
*/
|
|
|
|
|
+case OP_If: { /* jump, in1 */
|
|
|
|
|
+ int c;
|
|
|
|
|
+ c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3);
|
|
|
|
|
+ VdbeBranchTaken(c!=0, 2);
|
|
|
|
|
+ if( c ) goto jump_to_p2;
|
|
|
|
|
+ break;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* Opcode: IfNot P1 P2 P3 * *
|
|
/* Opcode: IfNot P1 P2 P3 * *
|
|
|
**
|
|
**
|
|
|
** Jump to P2 if the value in register P1 is False. The value
|
|
** Jump to P2 if the value in register P1 is False. The value
|
|
|
** is considered false if it has a numeric value of zero. If the value
|
|
** is considered false if it has a numeric value of zero. If the value
|
|
|
** in P1 is NULL then take the jump if and only if P3 is non-zero.
|
|
** in P1 is NULL then take the jump if and only if P3 is non-zero.
|
|
|
*/
|
|
*/
|
|
|
-case OP_If: /* jump, in1 */
|
|
|
|
|
case OP_IfNot: { /* jump, in1 */
|
|
case OP_IfNot: { /* jump, in1 */
|
|
|
int c;
|
|
int c;
|
|
|
- pIn1 = &aMem[pOp->p1];
|
|
|
|
|
- if( pIn1->flags & MEM_Null ){
|
|
|
|
|
- c = pOp->p3;
|
|
|
|
|
- }else{
|
|
|
|
|
- if( pIn1->flags & MEM_Int ){
|
|
|
|
|
- c = pIn1->u.i!=0;
|
|
|
|
|
- }else{
|
|
|
|
|
- c = sqlite3VdbeRealValue(pIn1)!=0.0;
|
|
|
|
|
- }
|
|
|
|
|
- if( pOp->opcode==OP_IfNot ) c = !c;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3);
|
|
|
VdbeBranchTaken(c!=0, 2);
|
|
VdbeBranchTaken(c!=0, 2);
|
|
|
- if( c ){
|
|
|
|
|
- goto jump_to_p2;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if( c ) goto jump_to_p2;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -101544,7 +101571,6 @@ SQLITE_PRIVATE int sqlite3FixSelect(
|
|
|
if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
|
|
if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
|
|
|
return 1;
|
|
return 1;
|
|
|
}
|
|
}
|
|
|
-#if 1
|
|
|
|
|
if( pSelect->pWith ){
|
|
if( pSelect->pWith ){
|
|
|
int i;
|
|
int i;
|
|
|
for(i=0; i<pSelect->pWith->nCte; i++){
|
|
for(i=0; i<pSelect->pWith->nCte; i++){
|
|
@@ -101553,7 +101579,6 @@ SQLITE_PRIVATE int sqlite3FixSelect(
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-#endif
|
|
|
|
|
pSelect = pSelect->pPrior;
|
|
pSelect = pSelect->pPrior;
|
|
|
}
|
|
}
|
|
|
return 0;
|
|
return 0;
|
|
@@ -219257,9 +219282,9 @@ static void print_elem(void *e, sqlite_int64 c, void* p){
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
/************** End of extension-functions.c *********************************/
|
|
/************** End of extension-functions.c *********************************/
|
|
|
-#if __LINE__!=219260
|
|
|
|
|
|
|
+#if __LINE__!=219285
|
|
|
#undef SQLITE_SOURCE_ID
|
|
#undef SQLITE_SOURCE_ID
|
|
|
-#define SQLITE_SOURCE_ID "2018-02-18 17:50:03 2df6bbf1b8ca881c8a465d6624de66fde4c5975ccae6b2f2dda392b137f5alt2"
|
|
|
|
|
|
|
+#define SQLITE_SOURCE_ID "2018-02-26 15:27:31 a983fa857048c748112c2f805f13aadeae43b43b3d27fa55433a3699b51calt2"
|
|
|
#endif
|
|
#endif
|
|
|
/* Return the source-id for this library */
|
|
/* Return the source-id for this library */
|
|
|
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
|
|
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
|