| Index: third_party/sqlite/src/src/vdbetrace.c | 
| diff --git a/third_party/sqlite/src/src/vdbetrace.c b/third_party/sqlite/src/src/vdbetrace.c | 
| index de123b550f9902c0afbfb2172e4affc5699ca067..507c2f12fc7d57083fda94bd329db820674c0ad4 100644 | 
| --- a/third_party/sqlite/src/src/vdbetrace.c | 
| +++ b/third_party/sqlite/src/src/vdbetrace.c | 
| @@ -12,6 +12,8 @@ | 
| ** | 
| ** This file contains code used to insert the values of host parameters | 
| ** (aka "wildcards") into the SQL text output by sqlite3_trace(). | 
| +** | 
| +** The Vdbe parse-tree explainer is also found here. | 
| */ | 
| #include "sqliteInt.h" | 
| #include "vdbeInt.h" | 
| @@ -45,19 +47,24 @@ static int findNextHostParameter(const char *zSql, int *pnToken){ | 
|  | 
| /* | 
| ** This function returns a pointer to a nul-terminated string in memory | 
| -** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the | 
| +** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the | 
| ** string contains a copy of zRawSql but with host parameters expanded to | 
| -** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1, | 
| +** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, | 
| ** then the returned string holds a copy of zRawSql with "-- " prepended | 
| ** to each line of text. | 
| ** | 
| +** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then | 
| +** then long strings and blobs are truncated to that many bytes.  This | 
| +** can be used to prevent unreasonably large trace strings when dealing | 
| +** with large (multi-megabyte) strings and blobs. | 
| +** | 
| ** The calling function is responsible for making sure the memory returned | 
| ** is eventually freed. | 
| ** | 
| ** ALGORITHM:  Scan the input string looking for host parameters in any of | 
| ** these forms:  ?, ?N, $A, @A, :A.  Take care to avoid text within | 
| ** string literals, quoted identifier names, and comments.  For text forms, | 
| -** the host parameter index is found by scanning the perpared | 
| +** the host parameter index is found by scanning the prepared | 
| ** statement for the corresponding OP_Variable opcode.  Once the host | 
| ** parameter index is known, locate the value in p->aVar[].  Then render | 
| ** the value as a literal in place of the host parameter name. | 
| @@ -80,11 +87,12 @@ char *sqlite3VdbeExpandSql( | 
| sqlite3StrAccumInit(&out, zBase, sizeof(zBase), | 
| db->aLimit[SQLITE_LIMIT_LENGTH]); | 
| out.db = db; | 
| -  if( db->vdbeExecCnt>1 ){ | 
| +  if( db->nVdbeExec>1 ){ | 
| while( *zRawSql ){ | 
| const char *zStart = zRawSql; | 
| while( *(zRawSql++)!='\n' && *zRawSql ); | 
| sqlite3StrAccumAppend(&out, "-- ", 3); | 
| +      assert( (zRawSql - zStart) > 0 ); | 
| sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); | 
| } | 
| }else{ | 
| @@ -117,34 +125,57 @@ char *sqlite3VdbeExpandSql( | 
| if( pVar->flags & MEM_Null ){ | 
| sqlite3StrAccumAppend(&out, "NULL", 4); | 
| }else if( pVar->flags & MEM_Int ){ | 
| -        sqlite3XPrintf(&out, "%lld", pVar->u.i); | 
| +        sqlite3XPrintf(&out, 0, "%lld", pVar->u.i); | 
| }else if( pVar->flags & MEM_Real ){ | 
| -        sqlite3XPrintf(&out, "%!.15g", pVar->r); | 
| +        sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r); | 
| }else if( pVar->flags & MEM_Str ){ | 
| +        int nOut;  /* Number of bytes of the string text to include in output */ | 
| #ifndef SQLITE_OMIT_UTF16 | 
| u8 enc = ENC(db); | 
| +        Mem utf8; | 
| if( enc!=SQLITE_UTF8 ){ | 
| -          Mem utf8; | 
| memset(&utf8, 0, sizeof(utf8)); | 
| utf8.db = db; | 
| sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); | 
| sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); | 
| -          sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z); | 
| -          sqlite3VdbeMemRelease(&utf8); | 
| -        }else | 
| +          pVar = &utf8; | 
| +        } | 
| #endif | 
| -        { | 
| -          sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z); | 
| +        nOut = pVar->n; | 
| +#ifdef SQLITE_TRACE_SIZE_LIMIT | 
| +        if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ | 
| +          nOut = SQLITE_TRACE_SIZE_LIMIT; | 
| +          while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } | 
| } | 
| +#endif | 
| +        sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z); | 
| +#ifdef SQLITE_TRACE_SIZE_LIMIT | 
| +        if( nOut<pVar->n ){ | 
| +          sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut); | 
| +        } | 
| +#endif | 
| +#ifndef SQLITE_OMIT_UTF16 | 
| +        if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); | 
| +#endif | 
| }else if( pVar->flags & MEM_Zero ){ | 
| -        sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); | 
| +        sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero); | 
| }else{ | 
| +        int nOut;  /* Number of bytes of the blob to include in output */ | 
| assert( pVar->flags & MEM_Blob ); | 
| sqlite3StrAccumAppend(&out, "x'", 2); | 
| -        for(i=0; i<pVar->n; i++){ | 
| -          sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); | 
| +        nOut = pVar->n; | 
| +#ifdef SQLITE_TRACE_SIZE_LIMIT | 
| +        if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; | 
| +#endif | 
| +        for(i=0; i<nOut; i++){ | 
| +          sqlite3XPrintf(&out, 0, "%02x", pVar->z[i]&0xff); | 
| } | 
| sqlite3StrAccumAppend(&out, "'", 1); | 
| +#ifdef SQLITE_TRACE_SIZE_LIMIT | 
| +        if( nOut<pVar->n ){ | 
| +          sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut); | 
| +        } | 
| +#endif | 
| } | 
| } | 
| } | 
|  |