Simplification and size reduction to the printf logic. Remove the bFlags

parameter from sqlite3VXPrintf() and sqlite3XPrintf().  Use sqlite3XPrintf()
instead of sqlite3_snprintf() for rendering P4 values in EXPLAIN output.

FossilOrigin-Name: 0bdb41c45aa1cc8e5c136aaa6605d54b401483bd
This commit is contained in:
drh 2016-01-30 12:50:25 +00:00
parent 8ea0056d5c
commit 5f4a686f8c
11 changed files with 121 additions and 139 deletions

View File

@ -1,5 +1,5 @@
C Make\suse\sof\scovering\sindexes\sin\sthe\sOR\soptimization.
D 2016-01-30T02:10:38.644
C Simplification\sand\ssize\sreduction\sto\sthe\sprintf\slogic.\s\sRemove\sthe\sbFlags\nparameter\sfrom\ssqlite3VXPrintf()\sand\ssqlite3XPrintf().\s\sUse\ssqlite3XPrintf()\ninstead\sof\ssqlite3_snprintf()\sfor\srendering\sP4\svalues\sin\sEXPLAIN\soutput.
D 2016-01-30T12:50:25.204
F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845
@ -290,10 +290,10 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
F src/btree.c f224ae877fde69d1a9d430f502edaf8502752dbe
F src/btree.c 5e3435a31afbe9d839c5ee2630b8390712847415
F src/btree.h 526137361963e746949ab966a910c7f455ac6b04
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
F src/build.c b4eba1e84752ec9cae7ff3dacd5a8b6d1ab8deb9
F src/build.c 0510844c48d80732aead74b5727403b493dd1cd5
F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
@ -303,7 +303,7 @@ F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da
F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6
F src/func.c ba6c03f9e440f5693086c08ee88e6e60212b3504
F src/func.c 42b24923328f65849f52f1659efb2a0907ad78fd
F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
@ -343,7 +343,7 @@ F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
F src/prepare.c db85f0451ba93ecb3c1e497c279abece5cb5aead
F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32
F src/printf.c 98a5cef7fc84577ab8a3098cfa48ecfa5a70b9f8
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
@ -352,7 +352,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4
F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
F src/sqliteInt.h 74e10a74116df0aec9d4a3e134f1a86cc34c2f14
F src/sqliteInt.h 5b552cc0eee50d519e2e020f16abbc68947b0e59
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@ -406,7 +406,7 @@ F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785
F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66
F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b
F src/trigger.c 72d876b2d0c66604a112362bdae07dae9b104816
F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3
F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3
@ -416,11 +416,11 @@ F src/vdbe.c 0686ef5ee103935548d1aa2c0c28e52f1ae6e5a8
F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337
F src/vdbeInt.h 171fdc5f6af4eeb0ff0559dbf0a71244d726a670
F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e
F src/vdbeaux.c 108124021ed02fa4fc6f90a53dcaf58ac3bab941
F src/vdbeaux.c 221631e40111b5efa96ea557c6e2e7f62fd32b2a
F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75
F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0
F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54
@ -428,7 +428,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251
F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a
F src/wherecode.c 3c4757ae85e8237808a4ec1a25c513d83e1395e0
F src/wherecode.c ef0d7019029624625416cdf32cc86604c970416f
F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@ -1422,8 +1422,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 512caa1ad30e6f699e2d006d5ab7674d55d2c746 6c520d5726e80b4251338c43c405270d150ea81e
R e4149e0b983ab1835709b124e27b8f90
T +closed 6c520d5726e80b4251338c43c405270d150ea81e
P 9de3d7123007636aa97da1c70bc34344b0391078
R 821c09620afbfbde9b9d6d9359867747
U drh
Z 625eb895cdbe3aba3d382c8d078d5321
Z e57134af984dbdd8b3338eb2a295687a

View File

@ -1 +1 @@
9de3d7123007636aa97da1c70bc34344b0391078
0bdb41c45aa1cc8e5c136aaa6605d54b401483bd

View File

@ -8805,9 +8805,9 @@ static void checkAppendMsg(
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
}
if( pCheck->zPfx ){
sqlite3XPrintf(&pCheck->errMsg, 0, pCheck->zPfx, pCheck->v1, pCheck->v2);
sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
}
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
va_end(ap);
if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
pCheck->mallocFailed = 1;
@ -9321,6 +9321,7 @@ char *sqlite3BtreeIntegrityCheck(
sCheck.aPgRef = 0;
sCheck.heap = 0;
sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
if( sCheck.nPage==0 ){
goto integrity_ck_cleanup;
}

View File

@ -4132,14 +4132,14 @@ void sqlite3UniqueConstraint(
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
if( pIdx->aColExpr ){
sqlite3XPrintf(&errMsg, 0, "index '%q'", pIdx->zName);
sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
}else{
for(j=0; j<pIdx->nKeyCol; j++){
char *zCol;
assert( pIdx->aiColumn[j]>=0 );
zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
sqlite3XPrintf(&errMsg, 0, "%s.%s", pTab->zName, zCol);
sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol);
}
}
zErr = sqlite3StrAccumFinish(&errMsg);

View File

@ -239,7 +239,8 @@ static void printfFunc(
x.nUsed = 0;
x.apArg = argv+1;
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
str.printfFlags = SQLITE_PRINTF_SQLFUNC;
sqlite3XPrintf(&str, zFormat, &x);
n = str.nChar;
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
SQLITE_DYNAMIC);

View File

@ -171,7 +171,6 @@ static char *getTextArg(PrintfArguments *p){
*/
void sqlite3VXPrintf(
StrAccum *pAccum, /* Accumulate results here */
u32 bFlags, /* SQLITE_PRINTF_* flags */
const char *fmt, /* Format string */
va_list ap /* arguments */
){
@ -211,11 +210,11 @@ void sqlite3VXPrintf(
char buf[etBUFSIZE]; /* Conversion buffer */
bufpt = 0;
if( bFlags ){
if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
if( pAccum->printfFlags ){
if( (bArgList = (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
pArgList = va_arg(ap, PrintfArguments*);
}
useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
useIntern = pAccum->printfFlags & SQLITE_PRINTF_INTERNAL;
}else{
bArgList = useIntern = 0;
}
@ -766,9 +765,9 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
setStrAccumError(p, STRACCUM_TOOBIG);
return N;
}else{
char *zOld = p->bMalloced ? p->zText : 0;
char *zOld = isMalloced(p) ? p->zText : 0;
i64 szNew = p->nChar;
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
szNew += N + 1;
if( szNew+p->nChar<=p->mxAlloc ){
/* Force exponential buffer size growth as long as it does not overflow,
@ -789,10 +788,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
if( !p->bMalloced && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
p->bMalloced = 1;
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_NOMEM);
@ -810,7 +809,7 @@ void sqlite3AppendChar(StrAccum *p, int N, char c){
if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
return;
}
assert( (p->zText==p->zBase)==(p->bMalloced==0) );
assert( (p->zText==p->zBase)==!isMalloced(p) );
while( (N--)>0 ) p->zText[p->nChar++] = c;
}
@ -828,7 +827,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
memcpy(&p->zText[p->nChar], z, N);
p->nChar += N;
}
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
}
/*
@ -864,13 +863,13 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
*/
char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
assert( (p->zText==p->zBase)==(p->bMalloced==0) );
assert( (p->zText==p->zBase)==!isMalloced(p) );
p->zText[p->nChar] = 0;
if( p->mxAlloc>0 && p->bMalloced==0 ){
if( p->mxAlloc>0 && !isMalloced(p) ){
p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
p->bMalloced = 1;
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{
setStrAccumError(p, STRACCUM_NOMEM);
}
@ -883,10 +882,10 @@ char *sqlite3StrAccumFinish(StrAccum *p){
** Reset an StrAccum string. Reclaim all malloced memory.
*/
void sqlite3StrAccumReset(StrAccum *p){
assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
if( p->bMalloced ){
assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
if( isMalloced(p) ){
sqlite3DbFree(p->db, p->zText);
p->bMalloced = 0;
p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
}
p->zText = 0;
}
@ -912,7 +911,7 @@ void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
p->nAlloc = n;
p->mxAlloc = mx;
p->accError = 0;
p->bMalloced = 0;
p->printfFlags = 0;
}
/*
@ -926,7 +925,8 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
assert( db!=0 );
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
acc.printfFlags = SQLITE_PRINTF_INTERNAL;
sqlite3VXPrintf(&acc, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
if( acc.accError==STRACCUM_NOMEM ){
db->mallocFailed = 1;
@ -966,7 +966,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
if( sqlite3_initialize() ) return 0;
#endif
sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3VXPrintf(&acc, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
return z;
}
@ -1011,7 +1011,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
}
#endif
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3VXPrintf(&acc, zFormat, ap);
return sqlite3StrAccumFinish(&acc);
}
char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
@ -1042,7 +1042,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3VXPrintf(&acc, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc));
}
@ -1071,7 +1071,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
char zBuf[500];
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3VXPrintf(&acc, zFormat, ap);
va_end(ap);
sqlite3StrAccumFinish(&acc);
fprintf(stdout,"%s", zBuf);
@ -1084,9 +1084,9 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument
** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
*/
void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
va_list ap;
va_start(ap,zFormat);
sqlite3VXPrintf(p, bFlags, zFormat, ap);
sqlite3VXPrintf(p, zFormat, ap);
va_end(ap);
}

View File

@ -2978,10 +2978,16 @@ struct StrAccum {
u32 nAlloc; /* Amount of space allocated in zText */
u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
u8 bMalloced; /* zText points to allocated space */
u8 printfFlags; /* SQLITE_PRINTF flags below */
};
#define STRACCUM_NOMEM 1
#define STRACCUM_TOOBIG 2
#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */
#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
/*
** A pointer to this structure is used to communicate information
@ -3298,10 +3304,8 @@ struct PrintfArguments {
sqlite3_value **apArg; /* The argument values */
};
#define SQLITE_PRINTF_INTERNAL 0x01
#define SQLITE_PRINTF_SQLFUNC 0x02
void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
void sqlite3VXPrintf(StrAccum*, const char*, va_list);
void sqlite3XPrintf(StrAccum*, const char*, ...);
char *sqlite3MPrintf(sqlite3*,const char*, ...);
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)

View File

@ -63,7 +63,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
}
va_start(ap, zFormat);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3VXPrintf(&acc, zFormat, ap);
va_end(ap);
if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
sqlite3StrAccumFinish(&acc);
@ -98,17 +98,17 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
char zLine[1000];
const struct Cte *pCte = &pWith->a[i];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
sqlite3XPrintf(&x, 0, "%s", pCte->zName);
sqlite3XPrintf(&x, "%s", pCte->zName);
if( pCte->pCols && pCte->pCols->nExpr>0 ){
char cSep = '(';
int j;
for(j=0; j<pCte->pCols->nExpr; j++){
sqlite3XPrintf(&x, 0, "%c%s", cSep, pCte->pCols->a[j].zName);
sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
cSep = ',';
}
sqlite3XPrintf(&x, 0, ")");
sqlite3XPrintf(&x, ")");
}
sqlite3XPrintf(&x, 0, " AS");
sqlite3XPrintf(&x, " AS");
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
@ -159,20 +159,20 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
StrAccum x;
char zLine[100];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){
sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
}else if( pItem->zName ){
sqlite3XPrintf(&x, 0, " %s", pItem->zName);
sqlite3XPrintf(&x, " %s", pItem->zName);
}
if( pItem->pTab ){
sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
}
if( pItem->zAlias ){
sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
}
if( pItem->fg.jointype & JT_LEFT ){
sqlite3XPrintf(&x, 0, " LEFT-JOIN");
sqlite3XPrintf(&x, " LEFT-JOIN");
}
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);

View File

@ -1117,28 +1117,27 @@ static int displayComment(
** Translate the P4.pExpr value for an OP_CursorHint opcode into text
** that can be displayed in the P4 column of EXPLAIN output.
*/
static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
static void displayP4Expr(StrAccum *p, Expr *pExpr){
const char *zOp = 0;
int n;
switch( pExpr->op ){
case TK_STRING:
sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken);
sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
break;
case TK_INTEGER:
sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue);
sqlite3XPrintf(p, "%d", pExpr->u.iValue);
break;
case TK_NULL:
sqlite3_snprintf(nTemp, zTemp, "NULL");
sqlite3XPrintf(p, "NULL");
break;
case TK_REGISTER: {
sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable);
sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
break;
}
case TK_COLUMN: {
if( pExpr->iColumn<0 ){
sqlite3_snprintf(nTemp, zTemp, "rowid");
sqlite3XPrintf(p, "rowid");
}else{
sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn);
sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
}
break;
}
@ -1170,21 +1169,19 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
case TK_NOTNULL: zOp = "NOTNULL"; break;
default:
sqlite3_snprintf(nTemp, zTemp, "%s", "expr");
sqlite3XPrintf(p, "%s", "expr");
break;
}
if( zOp ){
sqlite3_snprintf(nTemp, zTemp, "%s(", zOp);
n = sqlite3Strlen30(zTemp);
n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft);
if( n<nTemp-1 && pExpr->pRight ){
zTemp[n++] = ',';
n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight);
sqlite3XPrintf(p, "%s(", zOp);
displayP4Expr(p, pExpr->pLeft);
if( pExpr->pRight ){
sqlite3StrAccumAppend(p, ",", 1);
displayP4Expr(p, pExpr->pRight);
}
sqlite3_snprintf(nTemp-n, zTemp+n, ")");
sqlite3StrAccumAppend(p, ")", 1);
}
return sqlite3Strlen30(zTemp);
}
#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
@ -1196,72 +1193,57 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
*/
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
char *zP4 = zTemp;
StrAccum x;
assert( nTemp>=20 );
sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
switch( pOp->p4type ){
case P4_KEYINFO: {
int i, j;
int j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortOrder!=0 );
sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField);
i = sqlite3Strlen30(zTemp);
sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField);
for(j=0; j<pKeyInfo->nField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
const char *zColl = pColl ? pColl->zName : "nil";
int n = sqlite3Strlen30(zColl);
if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
zColl = "B";
n = 1;
}
if( i+n>nTemp-7 ){
memcpy(&zTemp[i],",...",4);
i += 4;
break;
}
zTemp[i++] = ',';
if( pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
}
memcpy(&zTemp[i], zColl, n+1);
i += n;
const char *zColl = pColl ? pColl->zName : "";
if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
}
zTemp[i++] = ')';
zTemp[i] = 0;
assert( i<nTemp );
sqlite3StrAccumAppend(&x, ")", 1);
break;
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
case P4_EXPR: {
displayP4Expr(nTemp, zTemp, pOp->p4.pExpr);
displayP4Expr(&x, pOp->p4.pExpr);
break;
}
#endif
case P4_COLLSEQ: {
CollSeq *pColl = pOp->p4.pColl;
sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
break;
}
case P4_FUNCDEF: {
FuncDef *pDef = pOp->p4.pFunc;
sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
#ifdef SQLITE_DEBUG
case P4_FUNCCTX: {
FuncDef *pDef = pOp->p4.pCtx->pFunc;
sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
#endif
case P4_INT64: {
sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
break;
}
case P4_INT32: {
sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i);
sqlite3XPrintf(&x, "%d", pOp->p4.i);
break;
}
case P4_REAL: {
sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
break;
}
case P4_MEM: {
@ -1269,11 +1251,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
if( pMem->flags & MEM_Str ){
zP4 = pMem->z;
}else if( pMem->flags & MEM_Int ){
sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
sqlite3XPrintf(&x, "%lld", pMem->u.i);
}else if( pMem->flags & MEM_Real ){
sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
sqlite3XPrintf(&x, "%.16g", pMem->u.r);
}else if( pMem->flags & MEM_Null ){
sqlite3_snprintf(nTemp, zTemp, "NULL");
zP4 = "NULL";
}else{
assert( pMem->flags & MEM_Blob );
zP4 = "(blob)";
@ -1283,30 +1265,24 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
#ifndef SQLITE_OMIT_VIRTUALTABLE
case P4_VTAB: {
sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
sqlite3XPrintf(&x, "vtab:%p", pVtab);
break;
}
#endif
case P4_INTARRAY: {
int i, j;
int i;
int *ai = pOp->p4.ai;
int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */
for(i=1; i<n; i++){
sqlite3XPrintf(&x, ",%d", ai[i]);
}
zTemp[0] = '[';
for(i=j=1; i<n && j<nTemp-7; i++){
if( j>1 ) zTemp[j++] = ',';
sqlite3_snprintf(nTemp-j, zTemp+j, "%d", ai[i]);
j += sqlite3Strlen30(zTemp+j);
}
if( i<n ){
memcpy(zTemp+j, ",...]", 6);
}else{
memcpy(zTemp+j, "]", 2);
}
sqlite3StrAccumAppend(&x, "]", 1);
break;
}
case P4_SUBPROGRAM: {
sqlite3_snprintf(nTemp, zTemp, "program");
sqlite3XPrintf(&x, "program");
break;
}
case P4_ADVANCE: {
@ -1321,6 +1297,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
}
}
}
sqlite3StrAccumFinish(&x);
assert( zP4!=0 );
return zP4;
}

View File

@ -128,9 +128,9 @@ char *sqlite3VdbeExpandSql(
if( pVar->flags & MEM_Null ){
sqlite3StrAccumAppend(&out, "NULL", 4);
}else if( pVar->flags & MEM_Int ){
sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
sqlite3XPrintf(&out, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r);
sqlite3XPrintf(&out, "%!.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
@ -151,17 +151,17 @@ char *sqlite3VdbeExpandSql(
while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
}
#endif
sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z);
sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
#ifdef SQLITE_TRACE_SIZE_LIMIT
if( nOut<pVar->n ){
sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
sqlite3XPrintf(&out, "/*+%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, 0, "zeroblob(%d)", pVar->u.nZero);
sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
}else{
int nOut; /* Number of bytes of the blob to include in output */
assert( pVar->flags & MEM_Blob );
@ -171,12 +171,12 @@ char *sqlite3VdbeExpandSql(
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);
sqlite3XPrintf(&out, "%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);
sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
}
#endif
}

View File

@ -76,7 +76,7 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
for(i=0; i<nEq; i++){
const char *z = explainIndexColumnName(pIndex, i);
if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
sqlite3XPrintf(pStr, 0, i>=nSkip ? "%s=?" : "ANY(%s)", z);
sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
}
j = i;
@ -135,13 +135,13 @@ int sqlite3WhereExplainOneScan(
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
if( pItem->pSelect ){
sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
}else{
sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
}
if( pItem->zAlias ){
sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
}
if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
const char *zFmt = 0;
@ -165,7 +165,7 @@ int sqlite3WhereExplainOneScan(
}
if( zFmt ){
sqlite3StrAccumAppend(&str, " USING ", 7);
sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
sqlite3XPrintf(&str, zFmt, pIdx->zName);
explainIndexRange(&str, pLoop);
}
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
@ -180,17 +180,17 @@ int sqlite3WhereExplainOneScan(
assert( flags&WHERE_TOP_LIMIT);
zRangeOp = "<";
}
sqlite3XPrintf(&str, 0, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
}
#endif
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
if( pLoop->nOut>=10 ){
sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
}else{
sqlite3StrAccumAppend(&str, " (~1 row)", 9);
}